0
点赞
收藏
分享

微信扫一扫

CF 584E(Anton and Ira-构造+贪心)


已知2个排列a,b,交换第i位位与第j位代价=abs(i-j) ,求把排列a变成排列b最小代价及任一合法方案

先把第一个排列变成顺序的

我们考虑对 i 最终要移到bi ,代价=|i−bi|
最小总代价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;
}


举报

相关推荐

0 条评论