POJ

来源:互联网 发布:淘宝答题秒杀辅助工具 编辑:程序博客网 时间:2024/06/14 00:44

题意:有K种块,每种高度为Hi,数量为Ci,拿这K种块去建塔,每种块再塔中所处的高度不能超过Ai,问塔最高能有多高;
思路:首先因为每种块所出的高度不能超过Ai,那么这个塔的最大高度不会超过max(Ai),以max(Ai)为数组大小,为了保持结果能最优应保证Ai小的在下层,所以应该以Ai从小到大排序,之后每次以Ai为背包容量去求解;

#include<iostream>#include<algorithm>#include<string>#include<cstring>#include<map>#include<queue>#include<cmath>#include<stack>#include<vector>#include<cstdio>#define MAXN 33000#define INF 0x3f3f3f3f#define lmid l,m,rt<<1#define rmid m+1,r,rt<<1|1#define ls rt<<1#define rs rt<<1|1#define Mod 1000000007#define i64 __int64#define LIMIT_ULL 100000000000000000using namespace std;int dp[40005];struct node{     int h,a,c;     bool operator<(const node &x)const     {          return a<x.a;     }}s[405];void dc(int w,int v,int sum){     if(w*v>=sum)     {          for(int i=w;i<=sum;i++)          {               dp[i]=max(dp[i],dp[i-w]+w);          }     }     else     {          int k=1;          while(k<v)          {               for(int i=sum;i>=k*w;i--)               {                    dp[i]=max(dp[i],dp[i-k*w]+k*w);               }               v-=k;               k*=2;          }          for(int i=sum;i>=v*w;i--)          {               dp[i]=max(dp[i],dp[i-v*w]+v*w);          }     }}int main(){     int n;     while(scanf("%d",&n)==1)     {          int sum=0;          for(int i=0;i<n;i++)          {               scanf("%d%d%d",&s[i].h,&s[i].a,&s[i].c);               sum=max(sum,s[i].a);          }          sort(s,s+n);          memset(dp,0,sizeof(dp));          for(int i=0;i<n;i++)          dc(s[i].h,s[i].c,s[i].a);          int j=0;          for(int i=0;i<=sum;i++)//显而易见dp[sum]不一定为最优解,所以要枚举出最大值          {               j=max(j,dp[i]);          }          cout<<j<<endl;     }     return 0;}