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;
}