http://poj.org/problem?id=2392

背包没有容量,对于每种木块,其能达到的最大高度a便可做为其容量。先用二进制优化减少数量,然后根据a的值排序,01背包时可以以每种木块可达到的最大高度为最大容量。RE一次,因为val的大小只开了401...这里是个易错点啊,二进制优化后的数量不确定。

代码:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#define Max(a, b)   a>b?a:b
int dp[40005] ;
struct Block{
    int h ;
    int a ;
}val[4001] ;
int cmp(const void *a, const void *b){
    return (*(Block *)a).a - (*(Block *)b).a ;
}
int main(){
    int n, i, j, count, h, c, a, max ;
    while(~scanf("%d", &n)){
        count = 0 ;
        memset(dp, 0sizeof(dp)) ;
        while(n--){
            scanf("%d%d%d", &h, &a, &c) ;
            //二进制优化
            i = 1 ;
            while(c>=i){
                val[count].h = h * i ;
                val[count++].a = a ;
                c -= i ;
                i *= 2 ;
            }
            if(c){
                val[count].h = h * c ;
                val[count++].a = a ;
            }
        }
        qsort(val, count, sizeof(val[0]), cmp) ;
        //01背包求解
        max = 0 ;
        for(i=0; i<count; i++)
            for(j=val[i].a; j>=val[i].h; j--)
                dp[j] = Max(dp[j], dp[j-val[i].h]+val[i].h) ;
        for(j=0; j<=val[i-1].a; j++)
            if(dp[j]>max)   max = dp[j] ;
        printf("%d\n", max) ;
    }
    return 0 ;

} 

posted on 2012-01-30 03:51  追逐.  阅读(218)  评论(0编辑  收藏  举报