Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 8701 | Accepted: 4135 |
Description
Input
Output
Sample Input
3 7 40 3 5 23 8 2 52 6
Sample Output
48
Hint
Source
大意:有K种block去建塔,每种每个都有一个高度H,用了当前的block塔的高度不能超出a,和每种的数量。求塔最高能建多高。
分析:这题就是一个多重背包,但有一点变动,必须先以a从小到大排序,因为如果先用了充许塔最高的block,而那种block的h很小,个数很少,更新自然就小,那么接下来小的就充许塔高越建越小,这样就不是我们所求的塔高了。如果先用a小的类形,就有变动更大的余地。
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; struct node { int h,a,c; }block[405]; bool cmp(node a,node b) { return a.a<b.a; } int main() { int dp[40005],k,maxa; while(scanf("%d",&k)>0) { memset(dp,0,sizeof(dp)); dp[0]=1; maxa=0; for(int i=0;i<k;i++) scanf("%d%d%d",&block[i].h,&block[i].a,&block[i].c); sort(block,block+k,cmp); int h,a,c; for(int i=0;i<k;i++) { h=block[i].h; a=block[i].a; c=block[i].c; if(maxa<a) maxa=a; if(h*c>=a) { for(int i=h;i<=a;i++) if(dp[i-h]) dp[i]=1; } else { int m=1; while(c>m) { for(int i=a;i>=h*m; i--) if(dp[i-h*m]) dp[i]=1; c-=m; m*=2; } if(c) for(int i=a;i>=h*c; i--) if(dp[i-h*c]) dp[i]=1; } } for( ; maxa>=0; maxa--) if(dp[maxa]) { printf("%d\n",maxa); break; } } }
原文地址:http://blog.csdn.net/u010372095/article/details/42032029