POJ 2392
这是一道多重背包,加了一点限制条件,要求不能让每一类型的砖头超过该类型的最大高度,这只需要加一个if语句就行了
if(j<=a[i])
dp[j]=max(dp[j],dp[j-hight[i]]+hight[i])
值得注意的是,应该将每种类型的砖头根据限制高度进行排序,也就是说要先从最大高度小的开始选,比如这种数据:5 10 1;1 1 1;最大高度应该是6,如果不先从小的开始选,那么就会首先取符合要求的5 10 1,但是第二块砖头的限制高度是1,取了第一块砖头之后高度已经是5了,就不能再取1 1 1了。所以要先从最大高度小的开始取。
做这道题的时候,最开始没有想到上面的那一点,所以卡了一段时间,后来改写的时候,将比较函数里面要做比较的元素弄错了,导致我怎么调试都不对,卡了更久,总之,自己欠缺的仍然是思维和仔细。
#include<stdio.h> #include<stdlib.h> #include<string.h> #define MAX_CASE 400 #define MAX_ALTT 40100 int max(int,int); int cmp(const void *,const void *); int mk_list(int,int,int); int top=1; struct node { int data; int a; }hight[MAX_ALTT]; int main() { int k; while(scanf("%d",&k)!=EOF) { int dp[MAX_ALTT],i,j,max_lmt=0,sum=0; memset(hight,0,sizeof(hight)); for(i=1,top=1;i<=k;i++) { int single_hight,lmt,amount; scanf("%d%d%d",&single_hight,&lmt,&amount); if(lmt>max_lmt) { max_lmt=lmt; } sum+=mk_list(single_hight,lmt,amount); } memset(dp,0,sizeof(dp)); qsort(&hight[1],top-1,sizeof(struct node),cmp); for(i=1;i<top;i++) { for(j=max_lmt;j>=hight[i].data;j--) { if(j<=hight[i].a) { dp[j]=max(dp[j],dp[j-hight[i].data]+hight[i].data); } } } int max=0; for(j=0;j<=max_lmt;j++) { if(dp[j]>max) { max=dp[j]; } } printf("%d\n",max); } return 0; } int max(int x,int y) { return x>y?x:y; } int mk_list(int single_hight,int limt,int amount) { int m=1,sum=0; while(m<amount) { hight[top].data=single_hight*m; sum+=hight[top].data; hight[top].a=limt; amount-=m; m=m*2; top++; } hight[top].data=single_hight*amount; sum+=hight[top].data; hight[top].a=limt; top++; return sum; } int cmp(const void *x,const void *y) { return (*(struct node*)x).a-(*(struct node*)y).a; }