题意
给出 n 大小的数组 A,B,可以选择交换 A 数组中的两个数,求 max ∑ i = 1 n ∣ A i − B i ∣ \sum_{i = 1}^{n}\left | A_i - B_i \right | ∑i=1n∣Ai−Bi∣;
思路
把 ∣ A i − B i ∣ \left | A_i - B_i \right | ∣Ai−Bi∣在数轴上表示就是 AI 和 Bi 的距离;
n = 2 时,交换偶数次答案不变,交换奇数次和交换 1 次的情况相同;
n > 2 时,确定如下情况交换 Ai 和 Aj会使结果更优
会发现结果增加了
2
(
m
i
n
(
A
i
,
B
i
)
−
m
a
x
(
A
j
,
B
j
)
)
2(min( A_i,B_i ) - max(A_j,B_j))
2(min(Ai,Bi)−max(Aj,Bj))
当k足够大的时候,找到最大值后,只需要对同一种性质的(min 或者 max)左右横跳交换即可,这样不会使得结果更劣;
AC代码
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <string>
#include <algorithm>
#include <queue>
#include <utility>
#include <stack>
#include <map>
#include <vector>
#include <set>
#include <iomanip>
#include <unordered_map>
#include <deque>
#define hz020 return
#define mes memset
#define mec memcpy
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll,ll> PII;
const double pi = acos(-1);
const int N = 500010;
const int null = 0x3f3f3f3f,INF = 1e9;
const ll mod = 998244353;
int n, k;
int a[N], b[N];
int c[N], d[N];
bool cmp(int x, int y)
{
return x > y;
}
int main()
{
cin >> n >> k;
ll ans = 0;
for (int i = 1; i <= n; i ++ ) cin >> a[i];
for (int i = 1; i <= n; i ++ )
{
cin >> b[i];
ans += abs(a[i] - b[i]);
c[i] = min(a[i], b[i]);
d[i] = max(a[i], b[i]);
}
if (n == 2)
{
if (k & 1) cout << abs(a[1] - b[2]) + abs(a[2] - b[1]);
else cout << ans << endl;
return 0;
}
sort(c + 1, c + 1 + n, cmp);
sort(d + 1, d + 1 + n);
for (int i = 1; i <= min(n, k); i ++ )
{
if (c[i] <= d[i]) break;
ans += 2 * (c[i] - d[i]);
}
cout << ans << endl;
hz020 0;
}