首页 > 技术文章 > Game of Swapping Numbers

GUOGaby 2021-07-19 16:43 原文

分析:

假如是
\(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<<'\n';
    
    return 0;
} 

推荐阅读