【POJ 3045】Cow Acrobats(贪心)

tech2022-08-16  302

题面:Cow Acrobats

题目大意

相当于有 n n n 头奶牛在叠罗汉。每头牛都有两个特质,一个是重量 w w w,一个是强壮度 s s s。 每头牛都有一个崩溃风险,该风险等于在她上面的所有奶牛的总重量减去她本身的强壮度。所以每头牛都要找到合适自己的位置。 求:确定所有奶牛的位置,从而使任何奶牛中的最大风险最小。

思路

芜湖~~先贪心试一下。 将每头牛按照 w + s w+s w+s 从小到大排序,这样就得到正确的答案啦哈哈哈哈哈哈。

贪心证明:

设最优解为 r e a l _ a n s real\_ans real_ans,自己方案的解为 a n s ans ans。

要证: a n s = r e a l _ a n s ans=real\_ans ans=real_ans 只需证:

a n s ≤ r e a l _ a n s ans\leq real\_ans ans≤real_ans a n s ≥ r e a l _ a n s ans\ge real\_ans ans≥real_ans

证明如下:

1、由题意可知,必然有 r e a l _ a n s ≤ a n s real\_ans\leq ans real_ans≤ans。

2、假设最优解不是按我们的算法来做的,则至少有一对牛是交换了位置的。已知第 k k k 头牛的特征为 ( w k , s k ) (w_k,s_k) (wk​,sk​),第 k + 1 k+1 k+1 头牛的特征为 ( w k + 1 , s k + 1 ) (w_{k+1},s_{k+1}) (wk+1​,sk+1​),且她们的风险分别为, r i s k , r i s k + 1 ris_k,ris_{k+1} risk​,risk+1​,则:

位置交换前交换后 k k k r i s k = ∑ i = 1 k − 1 w i − s k ris_k=\sum_{i=1}^{k-1}w_i-s_k risk​=∑i=1k−1​wi​−sk​ r i s k = ∑ i = 1 k − 1 w i + w k + 1 − s k ris_k=\sum_{i=1}^{k-1}w_i+w_{k+1}-s_k risk​=∑i=1k−1​wi​+wk+1​−sk​k+1 r i s k + 1 = ∑ i = 1 k w i − s k + 1 ris_{k+1}=\sum_{i=1}^kw_i-s_{k+1} risk+1​=∑i=1k​wi​−sk+1​ r i s k + 1 = ∑ i = 1 k − 1 w i − s k + 1 ris_{k+1}=\sum_{i=1}^{k-1}w_i-s_{k+1} risk+1​=∑i=1k−1​wi​−sk+1​

同时减去 ∑ i = 1 k − 1 w i \sum_{i=1}^{k-1}w_i ∑i=1k−1​wi​ 可得:

位置交换前交换后 k k k − s k -s_k −sk​ w k + 1 − s k w_{k+1}-s_k wk+1​−sk​ k + 1 k+1 k+1 w k − s k + 1 w_k-s_{k+1} wk​−sk+1​ − s k + 1 -s_{k+1} −sk+1​

由于 s , w ≥ 1 s,w\ge1 s,w≥1,所以有: w k + 1 − s k > − s k w_{k+1}-s_k>-s_k wk+1​−sk​>−sk​, w k − s k + 1 > − s k + 1 w_{k}-s_{k+1}>-s_{k+1} wk​−sk+1​>−sk+1​

所以,我们只要比较 w k + 1 − s k w_{k+1}-s_k wk+1​−sk​ 与 w k − s k + 1 w_k-s_{k+1} wk​−sk+1​ 的大小关系即可。 两边同时加上 s k + s k + 1 s_k+s_{k+1} sk​+sk+1​ 得: w k + 1 + s k + 1 w_{k+1}+s_{k+1} wk+1​+sk+1​ 与 w k + s k w_k+s_k wk​+sk​。 因为我们的贪心算法是按照 w + s w+s w+s 从小到大排序的。 所以, w k + 1 + s k + 1 ≥ w k + s k w_{k+1}+s_{k+1}\ge w_k+s_k wk+1​+sk+1​≥wk​+sk​。 所以,交换前的解要小于交换后的解,即 a n s ≤ r e a l _ a n s ans\leq real\_ans ans≤real_ans。

综上, a n s = r e a l _ a n s ans=real\_ans ans=real_ans。证毕。

代码

#include <bits/stdc++.h> #define sc scanf #define pf printf using namespace std; const int N = 5e4 + 10; const int INF = 0x3f3f3f3f; struct Node { int w, s; bool operator<(const Node &x) const { return w + s < x.w + x.s; } }cow[N]; int main() { int n; sc("%d", &n); for(int i = 0; i < n; i++) { int w, s; sc("%d %d", &w, &s); cow[i] = {w, s}; } sort(cow, cow + n); int ans = -INF, sum = 0; for(int i = 0; i < n; i++) { ans = max(ans, sum - cow[i].s); sum += cow[i].w; } pf("%d\n", ans); return 0; }
最新回复(0)