已知2个排列a,b,交换第i位位与第j位代价=abs(i-j) ,求把排列a变成排列b最小代价及任一合法方案
先把第一个排列变成顺序的
我们考虑对
i
最终要移到
最小总代价
ans=12∑ni=1|i−bi|
不妨假设这是答案,
那么每个数只能往一个方向挪,
我们从n开始,不断找可以交换的数交换,显然可以挪到n。
递归做完即可
#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define MEM(a) memset(a,0,sizeof(a));
#define pb push_back
#define mp make_pair
#define MAXN (2000+10)
#define fi first
#define se second
typedef long long ll;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int n;
int a[MAXN],b[MAXN],h[MAXN];
vector<pair<int,int> > p;
int main()
{
// freopen("CF584E.in","r",stdin);
cin>>n;
For(i,n) scanf("%d",&b[i]);
For(i,n) scanf("%d",&a[i]);
For(i,n) h[a[i]]=i;
For(i,n) b[i]=h[b[i]];
For(i,n) h[b[i]]=i;
int ans=0,k=0;
ForD(i,n) {
int pos=h[i];
Fork(j,pos+1,i)
{
if (b[j]<=pos)
{
p.pb(mp(j,pos));
ans+=abs(j-pos);
swap(b[j],b[pos]); swap(h[b[j]],h[b[pos]]);
pos=j;
}
}
}
int m=p.size();
cout<<ans<<endl<<m<<endl;
Rep(i,m) printf("%d %d\n",p[i].fi,p[i].se);
return 0;
}