POJ 2392 Space Elevator (多重背包 + 思路题)

题目链接:http://poj.org/problem?id=2392

Space Elevator
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 7783 Accepted: 3690

Description

The cows are going to space! They plan to achieve orbit by building a sort of space elevator: a giant tower of blocks. They have K (1 <= K <= 400) different types of blocks with which to build the tower. Each block of type i has height h_i (1 <= h_i <= 100) and is available in quantity c_i (1 <= c_i <= 10). Due to possible damage caused by cosmic rays, no part of a block of type i can exceed a maximum altitude a_i (1 <= a_i <= 40000). 

Help the cows build the tallest space elevator possible by stacking blocks on top of each other according to the rules.

Input

* Line 1: A single integer, K 

* Lines 2..K+1: Each line contains three space-separated integers: h_i, a_i, and c_i. Line i+1 describes block type i.

Output

* Line 1: A single integer H, the maximum height of a tower that can be built

Sample Input

3
7 40 3
5 23 8
2 52 6

Sample Output

48

Hint

OUTPUT DETAILS: 

From the bottom: 3 blocks of type 2, below 3 of type 1, below 6 of type 3. Stacking 4 blocks of type 2 and 3 of type 1 is not legal, since the top of the last type 1 block would exceed height 40.


题意:给你k种blocks,高度为hi,每种有ci个,约束条件是 想放置这个blocks的时候,当前总高度不超过ai。

分析:思考,如何将石块排序,能保证做01背包的正确性,有兴趣的可以看这里的第G题。

给代码具体去思考吧:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int n;
class blocks{
public:
	int h,l;
	bool operator <(const blocks &b)const{
		return b.h+l<b.l+h;
	}
}a[4000];
int dp[40005];
int max(int a,int b){return a>b?a:b;}
int min(int a,int b){return a<b?a:b;}
void binary_div(int h,int limit,int num){
	int i = 1;
	while(num){
		if(num >= i){
			a[n].h = h*i;
			a[n++].l = limit;
			num -= i;
		}else{
			a[n].h = h*num;
			a[n++].l = limit;
			num = 0;
		}
		i <<= 1;
	}
}
int main(){
	int t,h,ai,num,m;
	while(scanf("%d",&t)!=EOF){
		m = 0;n = 0;
		for (int i = 0; i < t; i++)
		{
			scanf("%d %d %d",&h,&ai,&num);
			binary_div(h,ai,num);
			m = max(m,ai);
		}
		memset(dp,0,sizeof(dp));
		sort(a,a+n);//排序
		int ans = 0;
		for (int i = 0; i < n; i++)
		{
			for (int j = a[i].l; j >= a[i].h; j--)
			{
				dp[j] = max(dp[j],dp[j-a[i].h]+a[i].h);
				ans = max(dp[j],ans);
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值