zoukankan      html  css  js  c++  java
  • poj 2392 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

     
    这道题和 poj 1742 有点类似,只是这道题要先按每个block的最大高度进行排序,这样做的目的是为了获得最优解,想想怎么证明?
    然后将dp数组初始化为-1,dp=-1表示取不到,dp[i]>=0表示取到i的时候还能剩下多少个
    最后结果就是从最大高度开始寻找dp[i]!=-1的i的值,直接输出即可
     
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<map>
     6 #include<set>
     7 using namespace std;
     8 #define N 406
     9 #define M 40006
    10 struct Node{
    11     int h,a,c;
    12 }block[N];
    13 int dp[M*N];
    14 bool cmp(Node a,Node b){
    15     return a.a<b.a;
    16 }
    17 int main()
    18 {
    19     int n;
    20     while(scanf("%d",&n)==1){
    21         for(int i=0;i<n;i++){
    22             scanf("%d%d%d",&block[i].h,&block[i].a,&block[i].c);
    23         }
    24         sort(block,block+n,cmp);
    25 
    26        memset(dp,-1,sizeof(dp));
    27        dp[0]=0;
    28        for(int i=0;i<n;i++){
    29            for(int j=0;j<=M;j++){
    30                if(dp[j]>=0){
    31                   dp[j]=block[i].c;
    32                }
    33                else if(j<block[i].h || dp[j-block[i].h]<=0){
    34                   dp[j]=-1;
    35                }
    36                else if(j>block[i].a){
    37                   dp[j]=-1;
    38                }
    39                else{
    40                   dp[j]=dp[j-block[i].h]-1;
    41                }
    42            }
    43        }
    44        for(int i=M;i>=0;i--){
    45           if(dp[i]!=-1){
    46              printf("%d
    ",i);
    47              break;
    48           }
    49        }
    50 
    51 
    52 
    53 
    54 
    55     }
    56     return 0;
    57 }
    View Code
  • 相关阅读:
    利用Trace.WriteLine定位难以重现的问题
    技术经验分享
    辞职小记
    残阳如血--读《忆秦娥·娄山关》 有感
    一个简单多线程等待窗口
    [转]Control的Invoke和BeginInvoke
    elk 改为使用 ik 中文分词器
    在 jenkins 的 pipeline 中使用分支参数
    centos8 下删除网桥 docker0
    vscode 实现组件之间的跳转
  • 原文地址:https://www.cnblogs.com/UniqueColor/p/4779397.html
Copyright © 2011-2022 走看看