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

31 篇文章 2 订阅
10 篇文章 0 订阅

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

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

我们考虑对 i 最终要移到bi ,代价= |ibi|
最小总代价 ans=12ni=1|ibi|

不妨假设这是答案,
那么每个数只能往一个方向挪,
我们从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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值