贪心。
考虑交换 $i$ 和 $i+1$ 这两头牛。
第 $i$ 头牛交换前的风险值:$w_1+w_2+…+w_{i-1}-s_i$。
第 $i$ 头牛交换后的风险值:$w_1+w_2+…+w_{i-1}+w_{i+1}-s_i$。
第 $i+1$ 头牛交换前的风险值:$w_1+w_2+…+w_i-s_{i+1}$。
第 $i+1$ 头牛交换后的风险值:$w_1+w_2+…+w_{i-1}-s_{i+1}$。
同时去掉 $w_1+w_2+…+w_{i-1}$:
第 $i$ 头牛交换前的风险值:$-s_i$。
第 $i$ 头牛交换后的风险值:$w_{i+1}-s_i$。
第 $i+1$ 头牛交换前的风险值:$w_i-s_{i+1}$。
第 $i+1$ 头牛交换后的风险值:$-s_{i+1}$。
而 $w_{i+1}-s_i > -s_i$ 且 $w_i-s_{i+1}>-s_{i+1}$
所以比较交换前的风险最大值和交换后的风险最大值只需比较 $w_i-s_{i+1}$ 和 $w_{i+1}-s_i$ 即可。
若 $w_i+s_i>w_{i+1}+s_{i+1}$,则 $w_i-s_{i+1} > w_{i+1}-s_i$,即交换后的风险最大值更小。
也就是说要尽量在 $w_i+s_i>w_{i+1}+s_{i+1}$ 的时候交换 $i$ 和 $i+1$,即按 $s_i$ 和 $w_i$ 之和升序排列。
所以就找到了最优策略,排好序模拟计算答案即可。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 5e4 + 10, inf = 2e9;
struct node {
int s, w, p;
}a[N];
int n;
bool cmp(node x,node y) {
return x.p < y.p;
}
signed main() {
cin >> n;
for(int i = 1;i <= n;i++) {
cin >> a[i].w >> a[i].s;
a[i].p = a[i].w + a[i].s;
}
sort(a + 1, a + 1 + n, cmp);
int res = -inf, sum = 0;
for(int i = 1;i <= n;i++) {
res = max(res, sum - a[i].s);
sum += a[i].w;
}
cout << res;
return 0;
}
代码参考:yxc。