HDU 4296 Buildings POJ 3045 Cow Acrobats(贪心)

题目连接:

http://acm.hdu.edu.cn/showproblem.php?pid=4296

http://poj.org/problem?id=3045

题意:有n个砖块,每个砖块有两个属性wi和si,将所有的砖块依次叠放起来,每个砖块得到一个值ti=sigama(W)-si,

其中W为在第i块砖上面的砖的总w值之和。要求求一种叠放次序,使得max(ti)最小?

思路:假设某一种叠放次序,对于第i,i+1两个砖块来说,他们的次序谁在上谁在下对i以前和i+1以后的都没有

影响。设W为第i块上面的值:(t1、t2分别为上面、下面的ti值)

(1)第i块在上,则t1=W-si,t2=W+wi-si+1,此时最大值p=max(t1,t2)=max(W-si,W+wi-si+1);

(2)第i+1块在上,则t1=W-si+1,t2=W+wi+1-si,此时最大值q=max(t1,t2)=max(W-si+1,W+wi+1-si);

若p<q,则max(W-si,W+wi-si+1)<max(W-si+1,W+wi+1-si),同时加上si+si+1-W,即:

max(si+1,si+wi)<max(si,si+1+wi+1),所以只需:si+wi<si+1+wi+1。所以只需按照si+wi升序排列,扫描一遍即可。

 

AC代码:

 

View Code
 1 #include <iostream>

 2 #include <cstdio>

 3 #include <algorithm>

 4 using namespace std;

 5 

 6 struct node

 7 {

 8     int weight,strength;

 9 };

10 

11 node a[500005];

12 int n;

13 

14 int cmp(node a,node b)

15 {

16     return (a.weight+a.strength)<(b.weight+b.strength);

17 }

18 

19 int main()

20 {

21     while(scanf("%d",&n)!=-1)

22     {

23         int i;

24         for(i=1;i<=n;i++) scanf("%d%d",&a[i].weight,&a[i].strength);

25         sort(a+1,a+n+1,cmp);

26         __int64 x=a[1].weight,pre=-a[1].strength;

27         for(i=2;i<=n;i++)

28         {

29             if(x-a[i].strength>pre) pre=x-a[i].strength;

30             x+=a[i].weight;

31         }

32         printf("%I64d\n",pre);

33     }

34     return 0;

35 }

 

 

 

你可能感兴趣的:(Build)