A

A - Space Elevator
Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u
Submit Status

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

题意:有一群牛要上太空,他们计划建一个太空梯(用一些石头垒),他们有k种不同类型的石头,每一种石头的高度为h,数量为c,由于会受到太空辐射,每一种石头不能超过这种石头的最大建造高度a,求解利用这些石头所能修建的太空梯的最高的高度.
 多重背包问题,与一般的多重背包问题所不同的知识多了一个限制条件就是某些"物品"叠加起来的"高度"不能超过一个值,于是我们可以对他们的最高可能达到高度进行排序,然就是一般的多重背包问题了


思路:
首先是录入数据,这一点比较简单,但是最好用scanf,因为它比cin快;
录入之后对各个数据按照最大的使用高度进行排序,就会转化成一个一般的多重背包为题,一开始我是用原始的多重背包做的麻烦并且也没有A了,最后看了一下题解,是因为每种块的使用个数的计算处理不当;
 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 #include<memory.h>
 7 using namespace std;
 8 int a[40005];
 9 struct node
10 {
11     int h;
12     int max;
13     int shu;
14 };
15 node num[40005];
16 int dp[40005];
17 bool cmp(node a,node b)
18 {
19     return a.max<b.max;
20 }
21 int main()
22 {
23 //    freopen("1.txt","r",stdin);
24    int i,j,k;
25    int m;
26    memset(dp,0,sizeof(dp));
27    dp[0]=1;
28    int sum[40005];
29    cin>>k;
30    for(i=0;i<k;i++)
31    {
32        scanf("%d%d%d",&num[i].h,&num[i].max,&num[i].shu);
33    }
34    sort(num,num+k,cmp);
35    m=num[k-1].max;
36    int ans=0;
37    for(i=0;i<k;i++)
38    {
39        memset(sum,0,sizeof(sum));
40        for(j=num[i].h;j<=num[i].max;j++)
41        {
42            if(!dp[j]&&dp[j-num[i].h]&&sum[j-num[i].h]<num[i].shu)
43            {
44                dp[j]=1;
45                sum[j]=sum[j-num[i].h]+1;//提柜条件,表示到达j高度已经用的砖的个数
46                if(ans<j)
47                ans=j;
48            }
49        }
50    }
51    cout<<ans<<endl;
52    return 0;
53 }
View Code




原文地址:https://www.cnblogs.com/zhangchengbing/p/3352888.html