奶牛玩杂技

非常棒的贪心题,我是完全没有想到解法。看了一波题解,证明如下:

若现在要处理两头牛 aa, bbww, ss 分别为 waw_a sas_a wbw_b sbs_b

设在在 aa, bb 上面全部牛的质量为 ww

假设 wa+sa>wb+sbw_a + s_a > w_b + s_b

aa 在上 bb 在下,易得

  • aa 压扁值为 wsaw - s_a
  • bb 压扁值为 w+wasbw + w_a - s_b

用作差法比较
wsa(w+wasb)=sawa+sbw - s_a - (w + w_a - s_b) = -s_a -w_a + s_b

根据 wa+sa>wb+sbw_a + s_a > w_b + s_b

wb>sawa+sb-w_b > -s_a - w_a + s_b

sawa+sb<0-s_a - w_a + s_b < 0

所以 wsa<w+wasbw-s_a < w+w_a-s_b

得 若最大压扁值需更新 w+wasbw+w_a-s_b 即为新的压扁值

aa 在下 bb 在下

  • bb 压扁值为 wsbw - s_b
  • aa 压扁值为 w+wbsaw + w_b - s_a

用作差法无法讨论出谁是新的压扁值

分类讨论

  • wsb<w+wbsaw-s_b < w+w_b-s_a 用作差法可得 w+wasb>w+wbsaw+w_a-s_b > w+w_b-s_a
  • wsb>w+wbsaw-s_b > w+w_b-s_a 同理得 w+wasb>wsbw+w_a-s_b > w-s_b

综上 bb 放在 aa 上面更优

即若牛从上到下记为 1~nn 必须满足 wi+si<wi+1+si+1w_i + s_i < w_{i+1} + s_{i+1}

显然我没有证等于的情况,读者自己去想

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <cstdio>
#include <iostream>
#include <cmath>
#include <algorithm>
struct cow {
int w, s, sum;
}a[50000];
bool cmp(cow a, cow b){
return a.sum < b.sum;
}
int main(){
int ans = -2100000000, n, w=0;
std::scanf("%d", &n);
for (int i=0; i<n; ++i){
std::scanf("%d%d", &a[i].w, &a[i].s);
a[i].sum = a[i].w + a[i].s;
}
std::sort(a, a+n, cmp);
for (int i=0;i<n;++i){
ans = std::max(ans, w-a[i].s);
w += a[i].w;
}
std::cout << ans;
return 0;
}
作者

Gesrua

发布于

2017-11-04

更新于

2020-11-21

许可协议