http://poj.org/problem?id=2392
背包没有容量,对于每种木块,其能达到的最大高度a便可做为其容量。先用二进制优化减少数量,然后根据a的值排序,01背包时可以以每种木块可达到的最大高度为最大容量。RE一次,因为val的大小只开了401...这里是个易错点啊,二进制优化后的数量不确定。
代码:
#include
#include
#include
#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, 0, sizeof(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
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 ;
#include
#include
#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, 0, sizeof(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
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 ;
}