Game of Swapping Numbers

分析:

假如是
(A:1 5)
(B:2 6)


可知通过一次替换变成
(A:1 2)
(B:5 6)
(发现原来的)ans(是)(2-1)+(6-5)(,那么现在的)ans(变成)(5-1)+(6-2)(,和原)ans(相比,新的)ans(更大,因为把-5变+5,把+2变-2)

(所以记录一个i的min(Ai,Bi)和max(Aj,Bj),寻找那些min(Ai,Bi)>max(Aj,Bj)的,ans+=2*[min(Ai,Bi)-max(Aj,Bj)],通过排序贪心求最优。)

(注意,如果原序列已经是最优情况,你再ans+=min(Ai,Bi)-max(Aj,Bj)会让ans变劣,所以要及时break;)

(那多的次数怎么办呢?已经排好的i,j一定是两个的A都大于B且不会i的min>j的max,所以他们互换答案不变,那就让他们换,¥ 直到k消耗完。)

code

#include <bits/stdc++.h>

using namespace std;

#define File(x) freopen("(x)","r",stdin)
#define pf printf
#define ull unsigned long long
#define db double
#define ll long long
#define MAXN 500010
#define MAXM 
#define P 
int n,k;
int A[MAXN],B[MAXN];
int dmin[MAXN],dmax[MAXN];
int main(){

	//ios::sync_with_stdio(false);
    cin>>n>>k;
    for(int i=1;i<=n;i++)scanf("%d",&A[i]);
    for(int i=1;i<=n;i++)scanf("%d",&B[i]);
    ll ans=0;
    for(int i=1;i<=n;i++){
        dmin[i]=2*min(A[i],B[i]);
        dmax[i]=2*max(A[i],B[i]);
        ans+=abs(A[i]-B[i]);
    } 
    sort(dmin+1,dmin+1+n); 
    sort(dmax+1,dmax+1+n); 
    for(int i=1;i<=n&&i<=k;i++) //前k大
    {
      if(dmin[n-i+1]<dmax[i])break;
        ans+=dmin[n-i+1]-dmax[i];
    }
    cout<<ans<<'
';
    
    return 0;
} 
原文地址:https://www.cnblogs.com/GUOGaby/p/15030912.html