POJ 2392 Space Elevator(多重背包)
2016-04-11 22:04
501 查看
题目链接:
POJ 2392 Space Elevator
题意:
有n种梯子,每种梯子的单位长度是height[i],个数是num[i],这种梯子能达到的最大高度是limit[i]。问由这n种梯子互相叠加最多能达到的高度是多少?
分析:
多重背包问题,可行性分析,不过先把梯子按照limit从小到大排序。
POJ 2392 Space Elevator
题意:
有n种梯子,每种梯子的单位长度是height[i],个数是num[i],这种梯子能达到的最大高度是limit[i]。问由这n种梯子互相叠加最多能达到的高度是多少?
分析:
多重背包问题,可行性分析,不过先把梯子按照limit从小到大排序。
//64656K 657MS #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const int MAX_N=410; const int MAX_HEIGHT=40010; int n; int dp[MAX_N][MAX_HEIGHT]; struct Block{ int height,num,limit; bool operator < (const Block& rhs) const{ if(limit!=rhs.limit) return limit < rhs.limit; else if(height!=rhs.height) return height < rhs.height; else return num < rhs.num; } }block[MAX_N]; int main() { //freopen("Oin.txt","r",stdin); block[0].height=block[0].num=0; block[0].limit=MAX_HEIGHT; while(~scanf("%d",&n)&&n){ memset(dp,0,sizeof(dp)); dp[0][0]=dp[1][0]=1; for(int i=1;i<=n;i++){ scanf("%d%d%d",&block[i].height,&block[i].limit,&block[i].num); } sort(block+1,block+n+1); for(int i=1;i<=n;i++){ if(i>1){ for(int k=0;k<=block[i-1].limit;k++){ dp[i][k]=dp[i-1][k]; } } for(int j=1;j<=block[i].num&&j*block[i].height<=block[i].limit;j++){ for(int k=j*block[i].height;k<=block[i].limit&&k-j*block[i].height<=block[i-1].limit;k++){ if(dp[i][k]==0&&dp[i-1][k-j*block[i].height]==1) { dp[i][k]=1; } } } } for(int i=block .limit;i>=0;i--){ if(dp [i]==1){ printf("%d\n",i); break; } } } return 0; }
//703K 63MS #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; const int MAX_HEIGHT=40010; const int MAX_N=410; int n; int dp[MAX_HEIGHT],used[MAX_HEIGHT]; struct Block{ int height,num,limit; bool operator < (const Block& rhs) const{ return limit<rhs.limit; } }block[MAX_N]; int main() { freopen("Oin.txt","r",stdin); while(~scanf("%d",&n)){ for(int i=1;i<=n;i++){ scanf("%d%d%d",&block[i].height,&block[i].limit,&block[i].num); } sort(block+1,block+n+1); memset(dp,0,sizeof(dp)); dp[0]=1; for(int i=1;i<=n;i++){\ memset(used,0,sizeof(used)); for(int j=block[i].height;j<=block[i].limit;j++){ if(dp[j]==0&&dp[j-block[i].height]==1&&used[j-block[i].height]<=block[i].num-1){ dp[j]=1; used[j]=used[j-block[i].height]+1; } } } for(int i=block .limit;i>=0;i--){ if(dp[i]==1){ printf("%d\n",i); break; } } } return 0; }
相关文章推荐
- 初学ACM - 组合数学基础题目PKU 1833
- POJ ACM 1001
- POJ ACM 1002
- 1611:The Suspects
- POJ1089 区间合并
- POJ 2635 The Embarrassed Cryptographe
- POJ 3292 Semi-prime H-numbers
- POJ 2773 HAPPY 2006
- POJ 3090 Visible Lattice Points
- POJ-2409-Let it Bead&&NYOJ-280-LK的项链
- POJ-1695-Magazine Delivery-dp
- POJ1523 SPF dfs
- POJ-1001 求高精度幂-大数乘法系列
- POJ-1003 Hangover
- POJ-1004 Financial Management
- 用单调栈解决最大连续矩形面积问题
- 2632 Crashing Robots的解决方法
- 1573 Robot Motion (简单题)
- POJ 1200 Crazy Search(简单哈希)
- 【高手回避】poj3268,一道很水的dijkstra算法题