华农oj Problem J: 幻化贪心/抽屉原理

Posted Roni

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了华农oj Problem J: 幻化贪心/抽屉原理相关的知识,希望对你有一定的参考价值。

Problem J: 幻化
Time Limit: 2 Sec  Memory Limit: 128 MB
Submit: 18  Solved: 3
[Submit][Status][Web Board]
Description
遇见你是我一世的春暖花开,

从此清风明月浩瀚星海。

不论结局,很高兴认识你。

她给了他一个长度为n的整数序列a[],他还给了她另外一个长度为n的整数序列b[],现在他想通过每次交换a[i],a[j]使序列a变成b,但是每次交换的代价是|j-i|。

请问最少的代价是多少呢?(a序列和b序列均是[1,n]的一个全排列)

Input
第一行一个数字T代表测试的组数。(T<=10)

对于每组测试第一行一个数字n表示序列的长度(1<=n<=2*10^5);

接下来2行第一行n个数字a1,a2,a3...an (1<=ai<=n)

第二行n个数字b1,b2,b3...bn(1<=bi<=n)

Output
对于每个测试输出一个整数,占一行,表示把a[]变成b[]所需要最少的交换代价。

Sample Input
2
4
1 2 3 4
4 3 2 1
4
2 1 4 3
1 2 3 4
Sample Output
4
2 
HINT

对于第一组样例1 4交换,2 3交换,代价是4 


第二组样例2 1交换,3 4交换,代价是2 
题意:有两个长度为n的排列p和s。要求通过交换使得p变成s。交换 pi 和 pj 的代价是|i-j|。要求使用最少的代价让p变成s。

考虑两个数字pi和pj,假如交换他们能使得pi到目标的距离减少,pj到目标的距离减少。那么应该交换他们,这是一个必要的操作,也是答案的下界。

如果每一次都能找到这样的两个数字,那么答案就是排列p中的每个数字在排列s的位置的距离差之和/2.这显然是答案的下界。

现在考虑证明这个下界是可以构造出来的。

考虑排列p中最后一个位置不对的数字,不妨设为pj,他的目标位置是pi,那么如果p[i+1,j]中有任意一个数的目标是pk(k<i),那么可以进行必要交换。

假设没有这样的一个数字使得他的目标是pk,一共有(j-i-1)个数,(j-i-2)个空,根据鸽巢原理,显然不存在这样的情况。

也就是说,对于排列p中最后一个位置不对的数字pj,目标位置是pi,pi总能在p[i+1,j]中找到一个数字pk,使得它们交换之后到目标的距离都减小了。

先将s映射成1-n的顺序排列,再将p根据同一映射函数映射成新的序列,得到新问题与原问题等价.

现在我们要做的就是将pi移到i位置上,我们可以先从最小的pi开始移动,这样当我们移动任何一个pi时,假设pi当前位置为x,我们都能保证pi<=x,如果pi==x,那么移动结束,否则我们可以一直将pi向左交换,使得其越来月接近目标位置,在这个过程中,pi是不会产生更多代价的,但是和pi交换的元素有可能产生更多代价,因此我们每次必定要挑选pj>=x的pj去和pi交换,这样才能保证总代价不变大,可以证明[i,x-1]区间内一定存在pj>=x.(可以用抽屉原理证明)
 
#include<iostream>
#include<stdlib.h>
using namespace std;

const int MAXN = 2e5+10;
int a[MAXN];

int main()
{
    int n,x;
    long long ans=0;
    cin>>n;
    for(int i=0;i<n;++i){cin>>x;a[x]=i;}
    for(int i=0;i<n;++i){cin>>x;ans+=abs(a[x]-i);}
    cout<<ans/2<<endl;
}

以上是关于华农oj Problem J: 幻化贪心/抽屉原理的主要内容,如果未能解决你的问题,请参考以下文章

华农oj Problem K: 负2进制有技巧构造/待补

华农oj 2192: hzk又在打人CRT合并/待补

题集k倍区间(抽屉原理)

2017-4-14:算法之路#2 (贪心抽屉原理计算几何)

山科SDUST OJ Problem J :连分数

南阳OJ-12-喷水装置贪心+区间覆盖