1 条题解

  • 1
    @ 2021-12-20 21:47:33

    显然先交换再加减和先加减再交换的总代价是一样的,那我们就考虑先交换再加减。

    考虑暴力怎么做,枚举你交换成某个排列 pp,那么答案显然是 y×f(p)+xapibiy\times f(p)+x\sum |a_{p_i}-b_i|。然后暴力枚举排列,计算贡献即可。

    如何优化?考虑到枚举排列这一步,再加上 n18n\le 18,容易联想到状压 DP。

    代码

    考场写的,比较菜。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    int n;
    ll x,y;
    ll a[25],b[25];
    ll dp[(1<<18)+5];
    int bitcnt(int sta){
    	int res=0;
    	while(sta){
    		sta-=sta&-sta;
    		res++;
    	}
    	return res;
    }
    int main(){
    	scanf("%d%lld%lld",&n,&x,&y);
    	for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
    	for(int i=1;i<=n;i++)scanf("%lld",&b[i]);
    	memset(dp,0x3f,sizeof(dp));
    	dp[0]=0;
    	for(int sta=1;sta<(1<<n);sta++){
    		int cnt=bitcnt(sta);
    		int now=cnt;
    		for(int i=1;i<=n;i++)if(sta&(1<<i-1))dp[sta]=min(dp[sta],dp[sta^(1<<i-1)]+abs(b[cnt]-a[i])*x+(now-1)*y),now--;
    	}
    	printf("%lld\n",dp[(1<<n)-1]);
    	return 0;
    }
    
    • 1

    信息

    ID
    57
    时间
    1000ms
    内存
    256MiB
    难度
    (无)
    标签
    递交数
    0
    已通过
    0
    上传者