您的位置:首页 > 其它

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

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

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

我们考虑对 ii 最终要移到bib_i ,代价=|i−bi||i-b_i|

最小总代价ans=12∑ni=1|i−bi|ans=\frac1 2 \sum_{i=1}^n|i-b_i|

不妨假设这是答案,

那么每个数只能往一个方向挪,

我们从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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: