Codeforces Round 920 (Div. 3) D Very Different Array
D Very Different Array
题意
给出两个长度分别为\(n,m\)的数组\(a,c\),\(n < m\),从\(c\)中选择\(n\)个数并找到一个序列使得\(D = \sum_{i=1}^{n} |a_i - c_i|\)尽可能大,求D的值
思路
假设如果\(m\)和\(n\)一样大,那么找到这个序列的方法很简单:将两个序列分别排序后将其中一个转置,就可以使\(D\)尽可能大(可以用数学归纳法证明,第一步假设对k个数的序列转置后匹配可使\(D\)最大)。
当\(m > n\)时,需要考虑的就是如何选择\(n\)个数字。将两个序列排序后,从前面的结论我们可以得出,如果要为\(a\)中的第一个数寻找对应的匹配数,那么必然是\(c\)中的最后一个数,同理要为\(a\)中的最后一个数寻找对应的匹配数,那么必然是\(c\)中的第一个数。因此我们只要对\(a\)中的第一和最后一个数的两个情况贪心地考虑哪一种情况的$ |a_i - c_i|$更优,然后就可以完成本题
主要代码
void solve()
{
int n, m;
cin >> n >> m;
vector<int> a(n + 10), b(m + 10);
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int j = 1; j <= m; j++)
cin >> b[j];
sort(a.begin() + 1, a.begin() + 1 + n);
sort(b.begin() + 1, b.begin() + 1 + m);
int l = 1, r = m;
int L = 1, R = n;
ll ans = 0;
while (L <= R) {
if (abs(a[L] - b[r]) > abs(a[R] - b[l])) {
ans += abs(a[L] - b[r]);
L++;
r--;
}
else{
ans += abs(a[R] - b[l]);
R--;
l++;
}
}
cout << ans << "\n";
}