• poj2392 Space Elevator(多重背包问题)


    Space Elevator
     
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 8569   Accepted: 4052

    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.
     
    题目大意:一群牛要上太空,给出n种石块,每种石块给出单块高度,每种石块都有个限定高度,超过这个高度这种石块就不能被使用了,最后面是每种石块的数量,要求用这些石块能组成的最大高度,并且不能超过限定的高度;
    思路:在进行多重背包之前要进行一次排序,将最大高度小的放在前面,只有这样才能得到最优解,如果将大的放在前面,后面有的小的就不能取到,排序之后就可以进行完全背包了
     AC代码(一): PZ
     1 #include<stdio.h>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<string.h>
     5 using namespace std;
     6 #define max 40005
     7 int a[max],b[max],c[max];
     8 struct pp
     9 {
    10     int x,y,z;
    11 }p[405];
    12 int cmp(pp p1,pp p2)//按照限定高度进行排序
    13 {
    14     return p1.y<p2.y;
    15 }
    16 int main()
    17 {
    18     int n;
    19     while((scanf("%d",&n))!=EOF)
    20     {
    21         int i,j,k,t;
    22         memset(a,0,sizeof(a));
    23         for(i=0;i<n;i++)
    24             scanf("%d %d %d",&p[i].x,&p[i].y,&p[i].z);
    25         sort(p,p+n,cmp);
    26         j=0;
    27         //暴力枚举所有的高度,a[s]=1; 表示s这个高度能够达到;
    28         for(i=0;i<n;i++)
    29         {
    30             int s=0,t=1,dd=0;
    31             while(s<=p[i].y&&t<=p[i].z) //小于限定的高度,并且小于限定的个数
    32             {
    33                 s=s+p[i].x;
    34                 for(k=0;k<j;k++) 
    35                     if(!a[b[k]+s] && (b[k]+s<=p[i].y)) //如果b[k]+s  这个高度没有出现过,并且小于限定的高低,高度可行
    36                     {
    37                         a[b[k]+s]=1;
    38                         c[dd++]=b[k]+s;
    39                     }
    40                 if(!a[s] && s<=p[i].y) 
    41                 {
    42                    a[s]=1;
    43                    b[j++]=s;
    44                 }
    45                 t++;              //统计当前石块使用个数
    46             }
    47             for(k=0;k<dd;k++)
    48                 b[j++]=c[k];
    49         }
    50         int ok=1;
    51         for(i=40000;i>=0;i--)
    52             if(a[i])
    53             {
    54                 printf("%d
    ",i);
    55                 ok=0;
    56                 break;
    57             }
    58         if(ok)
    59             printf("0
    ");
    60     }
    61     return 0;
    62 }
    View Code

     AC代码(二):

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<cstring>
     5 using namespace std;
     6 const int N = 400010;
     7 struct TT
     8 {
     9     int x,h,n;
    10 }a[410];
    11 int dp[N],cot[N];
    12 int cmp(TT x,TT y)//按照最高能堆多高进行排序;
    13 {
    14     if( x.h<y.h)  return 1;
    15     return 0;
    16 }
    17 int main()
    18 {
    19     int T,ans;
    20     while(cin>>T)
    21     {
    22         for(int i=0; i<T; i++)
    23             scanf("%d %d %d",&a[i].x,&a[i].h,&a[i].n);
    24             memset(dp,0,sizeof(0));
    25             sort(a,a+T,cmp);
    26             dp[0]  = 1;
    27             ans = 0;
    28             //采用暴力的方法,一直枚举j,看j最大能达到多少,则j就是要找的最大值;
    29             for(int i=0; i<T; i++)
    30             {
    31                 memset(cot,0,sizeof(cot));
    32                 for(int j = a[i].x; j<=a[i].h; j++)
    33                 {
    34                 // 如果j还没有达到并且dp[j-a[i].x] 大于0,并且当前模板的使用数不大于它的总数
    35                     if(!dp[j] && dp[j-a[i].x] && cot[j-a[i].x] < a[i].n) 
    36                     {
    37                         dp[j] = 1;
    38                         cot[j]=cot[j-a[i].x]+1;
    39                         if(j>ans) ans = j;
    40                     }
    41                 }
    42             }
    43        printf("%d
    ",ans);
    44     }
    45     return 0;
    46 }
    View Code
  • 相关阅读:
    Jenkins 完成安装环境配置
    Jenkins中文社区的所有镜像地址
    VueX源码分析(3)
    VueX源码分析(2)
    VueX源码分析(1)
    Element表单验证(2)
    Element表单验证(1)
    配置淘宝镜像,不使用怪异的cnpm
    React动态import()
    cnpm 莫名奇妙bug 莫名奇妙的痛
  • 原文地址:https://www.cnblogs.com/lovychen/p/4045101.html
Copyright © 2020-2023  润新知