poj2392 Space Elevator

http://www.elijahqi.win/2018/01/14/poj2392-space-elevator/
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.

Source
USACO 2005 March Gold
给定一些种类的块 每种块的叠放给定一个不可以超过的高度 然后再给定一下每种块的数量 给定每种块 单个块的高度是多少 求我最多能搭到多高 不妨设dp[i]表示这个高度我能否达到 据说是完全背包orz icefox巨佬 设num表示针对这个高度我当前第i号用了多少块 然后每次转移的时候枚举这个块的下界就是一个的高度 一直枚举到这个块最大到哪里 最后倒序判断一下输出答案即可


#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 440
#define inf 0x3f3f3f3f
using namespace std;
inline char gc(){
    static char now[1<<16],*S,*T;
    if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;}
    return *S++;
}
inline int read(){
    int x=0;char ch=gc();
    while(ch<'0'||ch>'9') ch=gc();
    while(ch<='9'&&ch>='0') x=x*10+ch-'0',ch=gc();
    return x;
}
struct node{
    int h,a,c;
}stone[N];
int dp[N*100],k,num[N*100];
inline bool cmp(node a,node b){
    return a.a<b.a;
}
int main(){
    //freopen("poj2392.in","r",stdin);
    k=read();
    for (int i=1;i<=k;++i) stone[i].h=read(),stone[i].a=read(),stone[i].c=read();
    sort(stone+1,stone+k+1,cmp);dp[0]=1;int ans=0;
    for (int i=1;i<=k;++i){
        memset(num,0,sizeof(num));
        for (int j=stone[i].h;j<=stone[i].a;++j){
            if (!dp[j]&&dp[j-stone[i].h]&&num[j-stone[i].h]+1<=stone[i].c){
                num[j]=num[j-stone[i].h]+1;dp[j]=1;
                ans=max(ans,j);
            }
        }
    }printf("%d",ans);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值