51nod1574排列转换
![](http://file.51nod.com/images/icon/star.png)
![](http://file.51nod.com/images/icon/plus.png)
现在有两个长度为n的排列p和s。要求通过交换使得p变成s。交换 pi 和 pj 的代价是|i-j|。要求使用最少的代价让p变成s。
Input
单组测试数据。 第一行有一个整数n (1≤n≤200000),表示排列的长度。 第二行有n个范围是1到n的整数,表示排列p。每个整数只出现一次。 第三行有n个范围是1到n的整数,表示排列s。每个整数只出现一次。
Output
输出一个整数,表示从排列p变到s最少要多少代价。
Input示例
样例输入1 4 4 2 1 3 3 2 4 1
Output示例
样例输出1 3
题目看上去有点难~~
贪心思想,如果有一个操作能使A,B都可以离自己的目标近一点,那么久换一换。如果每次都能找到这么两个数,那么答案就是
ans=sigma(place[pos[i]]-i);(不管有多少步,每一步每个数都渐渐靠近自己的目标。
我们考虑构造一个这样的做法。大概就是令最后一个不在自己目标上的数为a[j],其目标为a[i]。(易知i<j)
![](https://images2017.cnblogs.com/blog/1154530/201708/1154530-20170813141201632-1084800023.png)
#include<stdio.h> using namespace std; int pos[2000005],n; long long ans; int abs(int x) { if(x>0) return x; return -x; } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) { int x; scanf("%d",&x); pos[x]=i; } for(int i=1;i<=n;i++) { int x; scanf("%d",&x); ans+=abs(pos[x]-i); } ans/=2; printf("%lld\n",ans); }