题目连接:
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代码:
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 }