题目标题:
Space Elevator
题目连接:
http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=1635
题目类型:
动态规划 - 多重背包
数据结构:
struct LMIC_BLOCK
{
int h, a, c;
bool operator < ( const LMIC_BLOCK & K ) const
{
return a < K.a;
}
}
思路分析:
多重背包问题,
可以将每种砖块按照各自最大可以达到的高度进行排序,
所限制该种砖块的条件是 该砖块的数量和可以达到的高度
因为每种砖块的数量是有限的
所以是多重背包问题
解答的时候
讲多重背包拆分成01背包即可
证明:
略
源代码:
#include <iostream>
#include <stdio.h>
using namespace std;
struct LMIC_BLOCK
{
int h, a, c;
bool operator < ( const LMIC_BLOCK & K ) const
{
return a < K.a;
}
} blk[40005];
int dp[40005];
void _01pack( int p_k, LMIC_BLOCK p_pack )
{
int i;
p_pack.h *= p_k;
for( i = p_pack.a; i >= p_pack.h ; i -- )
{
dp[i] = max( dp[i], dp[i - p_pack.h] + p_pack.h );
}
}
void _compack( LMIC_BLOCK p_pack )
{
int i;
for( i = p_pack.h; i <= p_pack.a; i ++ )
{
dp[i] = max( dp[i], dp[i - p_pack.h] + p_pack.h );
}
}
void _multpack( LMIC_BLOCK p_pack )
{
if( p_pack.h * p_pack.c >= p_pack.a )
{
_compack( p_pack );
return ;
}
int k = 1;
while( k < p_pack.c )
{
_01pack( k, p_pack );
p_pack.c -= k;
k = k * 2;
}
_01pack( p_pack.c, p_pack );
}
int main()
{
int i, k;
scanf( "%d", &k );
{
memset( dp, 0, sizeof( dp ) );
for( i = 0; i < k; i ++ )
{
scanf( "%d%d%d", &blk[i].h, &blk[i].a, &blk[i].c );
}
sort( blk, blk + k );
for( i = 0; i < k; i ++ )
{
_multpack( blk[i] );
}
int max = -1;
for( i = 0; i <= 40004; i ++ )
{
if( max < dp[i] )
{
max = dp[i];
}
}
printf( "%d\n", max );
}
return 0;
}
/*
1
2 10 12
2
2 12 12
3 33 1
*/