非常棒的贪心题,我是完全没有想到解法。看了一波题解,证明如下:
若现在要处理两头牛 a, b 记 w, s 分别为 wa sa wb sb
设在在 a, b 上面全部牛的质量为 w
假设 wa+sa>wb+sb
若 a 在上 b 在下,易得
- a 压扁值为 w−sa
- b 压扁值为 w+wa−sb
用作差法比较
w−sa−(w+wa−sb)=−sa−wa+sb
根据 wa+sa>wb+sb
得 −wb>−sa−wa+sb
即 −sa−wa+sb<0
所以 w−sa<w+wa−sb
得 若最大压扁值需更新 w+wa−sb 即为新的压扁值
若 a 在下 b 在下
- b 压扁值为 w−sb
- a 压扁值为 w+wb−sa
用作差法无法讨论出谁是新的压扁值
分类讨论
- 若 w−sb<w+wb−sa 用作差法可得 w+wa−sb>w+wb−sa
- 若 w−sb>w+wb−sa 同理得 w+wa−sb>w−sb
综上 b 放在 a 上面更优
即若牛从上到下记为 1~n 必须满足 wi+si<wi+1+si+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; }
|