【刷水-贪心】BZOJ1629-[Usaco2007 Demo]Cow Acrobats

【题目大意】

有n个头牛,给出体重和力量。每个牛的危险值等于它上面的牛的体重总和减去它的力量值,求所有方案中危险值最大值的最小值。

【思路】

贪心。一开始脑补的贪心是体重大的先放下面,体重相同的根据力量值来排。但是其实是不对的QAQ

这里有详细证明:

首先要想到,对于相邻的两头牛,交换它们的位置,仅仅会影响他们两个的risk值 然后,对于最优系列的相邻的两头牛 w1 s1 w2 s2 最顶上的那头的顶上的牛的质量和为sum。

那么第一头牛的risk就是 sum - s1……r1

第二头的为sum + w1 - s2……r2

假如交换位置之后:

sum - s2……r3

sum + w2 - s1……r4

有:max(r1,r2) < max(r3,r4)——r1..r4分别对应四个risk。

那么,有四种假设。因为明显有 r1<r4,r2>r3 所以只剩下:

1.r1 < r3 &&( r1 > r2 && r3 > r4)

2.r2 < r4 && (r2 > r1 && r4 > r3)

对于1: s2 - s1 > w1 && s1 - s2 > w2,因为w1,w2都大于0,所以不符合。 所以只剩下2。

得到:w1 + s1 < w2 + s2 综上,得出w+s最大的必定在最底下,按照w+s排序得到的就是最优序列。 顺便,要注意一下,risk是可以为负数的,所以初始化的时候不可以为0。

唯一的坑点就是,ans的初始值要很小……因为可能risk都是负的。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 const int MAXN=50000+50;
 8 const int INF=1e9;
 9 struct node
10 {
11     int w,s;
12     bool operator < (const node &x) const
13     {
14         if (w+s<x.w+x.s) return 1;else return 0;
15     }
16 }cow[MAXN];
17 
18 int main()
19 {
20     int n;
21     scanf("%d",&n);
22     for (int i=1;i<=n;i++) scanf("%d%d",&cow[i].w,&cow[i].s);
23     sort(cow+1,cow+n+1);
24     int sum=0,ans=-INF;
25     for (int i=1;i<=n;i++)
26     {
27         int now=sum-cow[i].s;
28         ans=max(ans,now);
29         sum+=cow[i].w;
30     }
31     printf("%d",ans);
32     return 0;
33 }

 

posted @ 2016-10-25 23:21  iiyiyi  阅读(128)  评论(0编辑  收藏  举报