TOJ 1635


题目标题:

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 
#include 

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
*/


你可能感兴趣的:(ACM解题报告,动态规划)