poj 2392 Space Elevator (多重背包)

背包没有容量,对于每种木块,其能达到的最大高度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 ;

} 

你可能感兴趣的:(poj)