http://poj.org/problem?id=2392
Space Elevator
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 8063 | Accepted: 3812 |
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.
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.
* 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题意:有K种积木,告诉你每种积木的高度,数量,和它能到达的最大高度,问积木能堆出的最大高度为多少?
假设没有最大高度这个限制,我们把所有积木堆在一起一定是最高的。加上这个限制以后,怎样堆才是最优的呢?显然贪心的将最大高度较低的物品放在下面一定比最大高度较高放在下面更优。但是我们知道了积木堆的顺序,还是不能解决问题,因为一种积木还有不用与用以及用多少个这几种策略。这个问题我们可以用动态规划来解决。具体细节见代码:
#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<vector>
#include<algorithm>
#include<queue>
#include<stack>
#define nn 41000
#define inff 0x3fffffff
#define mod 1000000007
#define eps 1e-9
using namespace std;
typedef long long LL;
int n;
struct node
{
int h,a,c;
}w[510];
bool dp[41000];//dp[i][j]表示前i种积木,高度为j能否达到,当然前一维可以优化掉。
bool cmp(node xx,node yy)
{
return xx.a<yy.a;
}
int main()
{
int i,j,k;
while(scanf("%d",&n)!=EOF)
{
for(i=1;i<=n;i++)
{
scanf("%d%d%d",&w[i].h,&w[i].a,&w[i].c);
}
memset(dp,false,sizeof(dp));
dp[0]=true;
sort(w+1,w+n+1,cmp);
for(i=1;i<=n;i++)
{
for(j=w[i].a;j>=0;j--)
{
for(k=1;k<=w[i].c;k++)
{
if(j-k*w[i].h>=0)
dp[j]=dp[j-k*w[i].h]?true:dp[j];
}
}
}
for(i=w[n].a;i>=0;i--)
if(dp[i])
break;
printf("%d\n",i);
}
return 0;
}