题意:
给你两个长度均为n的序列ai,bi,要求你交换的一个序列K次使得 值最大。
啊,这个贪心,真的好难想
首先,我们先不考虑交换,计算abs(ai-bi)的和,然后如果我们要将ai,bi,aj,bj进行一次交换,也就是将
max(ai,bi)-min(ai,bi)+max(aj,bj)-min(aj,bj)
变成
max(ai,bi)-min(aj,bj)+min(ai,bi)-max(aj,bj)
那么就需要在原来的sum上加上2*(min(ai,bi)-max(aj,bj))
所以要使这k次所增加的效益最大,排两次序,就依次用最大的min(ai,bi)减去最小的max(aj,bj),直至将k次用完或者,加上的这个数<=0(敲重点!!!!)
因为在n>2的时候,总可以找到一对交换但不影响结果的情况
所以在n>2时,恰好k次和至多k次是一样的,n=2单独考虑就行
emmm
思路想清楚就发现很简单
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 500010;
int a[N], b[N];
int mi[N], ma[N];
typedef long long ll;
bool cmp1(int x, int y)
{
return x > y;
}
bool cmp2(int x, int y)
{
return x < y;
}
int main()
{
int n, k;
cin >> n >> k;
ll sum = 0;
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
for (int i = 0; i < n; i++)
{
cin >> b[i];
}
if(n==2)
{
if(k>=1)
{
sum=max(abs(a[0]-b[1])+abs(a[1]-b[0]),abs(a[0]-b[0])+abs(a[1]-b[1]));
}
else
{
sum=abs(a[0]-b[0])+abs(a[1]-b[1]);
}
cout<<sum<<endl;
return 0;
}
for (int i = 0; i < n; i++)
{
mi[i] = min(a[i], b[i]);
ma[i] = max(a[i], b[i]);
sum += abs(a[i]-b[i]);
}
sort(mi, mi + n, cmp1);
sort(ma, ma + n, cmp2);
for (int i = 0; i <k; i++)
{
if (mi[i] - ma[i] <= 0)
{
break;
}
sum += 2 * (mi[i]-ma[i]);
}
cout << sum << endl;
return 0;
}