Space Elevator
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 6422 | Accepted: 2965 |
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 先按照限制的高度进行从小到大排序。之后就是简单的多重背包了。
/* POJ 2392 G++ 157ms */ #include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; const int MAXN=410; struct Node { int h,c; int lim; }node[MAXN]; int dp[50000]; int H; void ZeroOnePack(int cost,int weight,int lim) { for(int i=lim;i>=cost;i--) dp[i]=max(dp[i],dp[i-cost]+weight); } void CompletePack(int cost,int weight,int lim) { for(int i=cost;i<=lim;i++) dp[i]=max(dp[i],dp[i-cost]+weight); } void MultiplePack(int cost,int weight,int amount,int lim) { if(cost*amount>=lim)CompletePack(cost,weight,lim); else { for(int k=1;k<amount;) { ZeroOnePack(k*cost,k*weight,lim); amount-=k; k<<=1; } ZeroOnePack(amount*cost,amount*weight,lim); } } bool cmp(Node a,Node b) { return a.lim<b.lim; } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int n; while(scanf("%d",&n)!=EOF) { H=0; for(int i=0;i<n;i++) { scanf("%d%d%d",&node[i].h,&node[i].lim,&node[i].c); if(node[i].lim>H)H=node[i].lim; } for(int i=0;i<=H;i++)dp[i]=0; sort(node,node+n,cmp); for(int i=0;i<n;i++) MultiplePack(node[i].h,node[i].h,node[i].c,node[i].lim); int ans=0; for(int i=0;i<=H;i++)ans=max(ans,dp[i]);//这个过程一定要 printf("%d\n",ans); } return 0; }
/* POJ 2392 G++ 141ms */ #include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; const int MAXN=410; struct Node { int h,c; int lim; }node[MAXN]; bool dp[50000]; int H; int ans; void ZeroOnePack(int cost,int lim) { for(int i=lim;i>=cost;i--) if(dp[i-cost]&&(!dp[i])) { dp[i]=true; ans=max(ans,i); } } void CompletePack(int cost,int lim) { for(int i=cost;i<=lim;i++) if(dp[i-cost]&&(!dp[i])) { dp[i]=true; ans=max(ans,i); } } void MultiplePack(int cost,int amount,int lim) { if(cost*amount>=lim)CompletePack(cost,lim); else { for(int k=1;k<amount;) { ZeroOnePack(k*cost,lim); amount-=k; k<<=1; } ZeroOnePack(amount*cost,lim); } } bool cmp(Node a,Node b) { return a.lim<b.lim; } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int n; while(scanf("%d",&n)!=EOF) { H=0; for(int i=0;i<n;i++) { scanf("%d%d%d",&node[i].h,&node[i].lim,&node[i].c); if(node[i].lim>H)H=node[i].lim; } for(int i=0;i<=H;i++)dp[i]=false; dp[0]=true; sort(node,node+n,cmp); ans=0; for(int i=0;i<n;i++) MultiplePack(node[i].h,node[i].c,node[i].lim); printf("%d\n",ans); } return 0; }