仔细想一想,必须先要从a_i最小的开始装,这样才能保证高度最高,先根据a_i的大小对每个塔的信息整体进行从小到大排序,然后就是多重背包问题。
多重背包不懂的去百度搜《背包九讲》,第4讲就是多重背包,水过。
View Code
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int n; bool dp[40003]; struct node { int a, h, c; }p[43]; bool cmp(node a, node b) { return a.a<b.a; } int main() { int i, j; while(~scanf("%d",&n)) { for(i=1;i<=n;i++) scanf("%d%d%d",&p[i].h,&p[i].a,&p[i].c); sort(p+1,p+n+1,cmp); memset(dp,0,sizeof(dp)); dp[0]=1; for(i=1;i<=n;i++) { if(p[i].h*p[i].c>=p[i].a) { for(j=p[i].h;j<=p[i].a;j++) if(dp[j-p[i].h])dp[j]=1; } else { int k=1; while(k<p[i].c) { for(j=p[i].a;j>=p[i].h*k;j--) if(dp[j-p[i].h*k])dp[j]=1; p[i].c-=k; k*=2; } for(j=p[i].a;j>=p[i].h*p[i].c;j--) if(dp[j-p[i].h*p[i].c])dp[j]=1; } } for(i=p[n].a;i>=0;i--) if(dp[i]){printf("%d\n",i);break;} } return 0; }