​题目传送门​

一、算法思路

与国王游戏的贪心策略相似, 我们先分析每头牛的危险值 = 他前面牛的\(w\)(重量值)和 - 自身的\(s\)(强壮值),要使每头牛的危险值最小,这显然是与\(w\) 和 \(s\)同时相关,所以先 \(yy\) 出一种作法按每头牛的\(w + s\)进行升序排序(题见多了可能就会有这种题感)。

数学分析:

交换前

交换后

\(i\)

$$\sum_{j=1}^{i-1}w_j-s_i$$

$$\sum_{j=1}^{i-1}w_j+w_{i+1}-s_i$$

\(i+1\)

$$\sum_{j=1}^{i}w_j-s_{i+1}$$

$$\sum_{j=1}^{i-1}w_j-s_{i+1}$$

其他牛的危险值显然不变,所以分析交换前后这两头牛中最大的危险值即可。

将上述式子进行化简,每个式子减去$$\sum_{j=1}^{i-1}w_j$$得到如下式子

交换前

交换后

\(i\)

\(-s_i\)

\(w_{i+1}-s_i\)

\(i+1\)

\(w_{i}-s_{i+1}\)

\(-s_{i+1}\)

\(\because\) \(s,w\)都是正数

\(\therefore\) \(w_i-s_{i+1}>-s_{i+1},w_{i+1}-s_i>-s_i\)

所以,交换前后的最大值,就是在比较 \(w_i-s_{i+1},w_{i+1}-s_i\):

当\(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}\)时,交换前更优。

作法: 按每头牛的 \(w + s\) 进行排序, 当存在逆序时就进行交换(即升序排序),然后根据题意算出每头牛的危险值记录其中的最大值即可。

二、完整代码

#include <bits/stdc++.h>

using namespace std;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
const int N = 50010;
PII cow[N];
int n;

int main() {
//优化输入
ios::sync_with_stdio(false);
cin >> n; //奶牛的数量
for (int i = 0; i < n; i++) {
int s, w; //牛的重量和强壮程度
cin >> w >> s;
cow[i] = {w + s, w}; //之所以这样记录数据,是因为我们找到贪心的公式,按 wi+si排序
}
//排序
sort(cow, cow + n);

//最大风险值
int res = -INF, sum = 0;
for (int i = 0; i < n; i++) {
int s = cow[i].first - cow[i].second, w = cow[i].second;
res = max(res, sum - s); //res为最大风险值
sum += w; //sum=w1+w2+w3+...+wi
}
printf("%d\n", res);
return 0;
}