题意:
给定两个长度为
n
n
n的数组
A
,
B
A,B
A,B,你最多能交换
k
k
k次
A
A
A数组中的数,求
∑
i
=
1
n
∣
A
i
−
B
i
∣
\sum_{i=1}^{n}\lvert A_i-B_i\rvert
∑i=1n∣Ai−Bi∣最大是多少
思路:为了方便理解,我们令两者大一点的数为 A i A_i Ai,小一点的数为 B i B_i Bi,那么答案 ∑ i = 1 n ∣ A i − B i ∣ \sum_{i=1}^{n}\lvert A_i-B_i\rvert ∑i=1n∣Ai−Bi∣即可变为 ∑ i = 1 n A i − B i \sum_{i=1}^{n} A_i-B_i ∑i=1nAi−Bi,考虑 i , j i,j i,j交换带来的影响,其原本的答案计算为 A i − B i + A j − B j A_i-B_i+A_j-B_j Ai−Bi+Aj−Bj交换后要么变为① A i − A j + B i − B j A_i-A_j+B_i-B_j Ai−Aj+Bi−Bj要么变为② A i − B j + A j − B i A_i-B_j+A_j-B_i Ai−Bj+Aj−Bi或者③ B j − A i + B i − A j B_j-A_i+B_i-A_j Bj−Ai+Bi−Aj,由于原本计算出来的答案即为正数,那么易证②与③交换所带来的的影响为0,因此只需考虑交换①带来的影响,那么易观察得出,交换所得②增加了 2 ∗ ( B i − A j ) 2*(B_i-A_j) 2∗(Bi−Aj),因此对所有 A A A与 B B B排序求答案即可
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=5e5+10;
const int maxc=26;
int A[maxn],B[maxn];
int n,k;
bool cmp(int x,int y)
{
return x>y;
}
signed main()
{
cin>>n>>k;
ll ans=0;
for(int i=1,x; i<=2*n; i++)
{
if(i<=n)
cin>>A[i];
else
cin>>B[i-n];
}
if(n==2)
{
if(k%2)
{
swap(A[1],A[2]);
}
ans=ans+abs(A[1]-B[1])+abs(A[2]-B[2]);
cout<<ans<<endl;
return 0;
}
vector<int> vch,vcl;
for(int i=1; i<=n; i++)
{
vch.push_back(min(A[i],B[i]));
vcl.push_back(max(A[i],B[i]));
ans+=abs(A[i]-B[i]);
}
sort(vch.begin(),vch.end(),cmp);
sort(vcl.begin(),vcl.end());
for(int i=0; i<vcl.size()&&i<k; i++)
{
if(vch[i]<vcl[i])
break;
ans+=2*(vch[i]-vcl[i]);
}
cout<<ans<<endl;
return 0;
}