题目传送门

一、算法思路

与国王游戏的贪心策略相似, 我们先分析每头牛的危险值 = 他前面牛的\(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;
}

相关文章:

  • 2022-12-23
  • 2021-06-14
  • 2021-05-29
  • 2022-12-23
  • 2022-01-18
  • 2021-06-03
  • 2021-12-16
  • 2021-06-19
猜你喜欢
  • 2021-10-10
  • 2022-12-23
  • 2022-12-23
  • 2022-02-13
  • 2022-12-23
  • 2022-01-04
相关资源
相似解决方案