poj 2392 Space Elevator(动态规划)

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.

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
题意:有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;
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值