POJ_2392_Space_Elevator_(动态规划,背包)

描述


http://poj.org/problem?id=2392

磊方块,每种方块有数量,高度,以及该种方块所能处在的最高高度.问最高磊多高?

Space Elevator
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 10511   Accepted: 4997

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

分析


看起来很像多重背包问题,只不过这里的重量和价值是一样的,并且多了一个所能处在的最高高度的限制.

考虑这个限制,设i种所能处在的最高高度为hi.对于两种方块i,j,设hi<hj.那么放的时候肯定是先放i比较好,因为如果先放了j的话,i只能放在j的上面,对于一种合法的情况,我们把在下面的h较大的,和在上面的h较小的调换位置是可以的,但是把在下面的h较小的和在上面的h较大的调换位置却不一定可以,所以应该尽量避免h小的放在上面,所以要先放i.放第i种方块的时候背包的容量上限是hi.

注意:

1.数组大小,好几次都没开够,没有好好看数据范围啊...

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <algorithm>
 4 #define for1(i,a,n) for(int i=(a);i<=(n);i++)
 5 #define read(a) a=getnum()
 6 using namespace std;
 7 
 8 const int maxn=400+5,maxh=40000+5;
 9 int n;
10 int dp[maxh];
11 struct node { int h,v,m; }a[maxn];
12 
13 inline int getnum(){int r=0;char c;c=getchar();while(c<'0'||c>'9')c=getchar();while(c>='0'&&c<='9'){r=r*10+c-'0';c=getchar();}return r;}
14 
15 bool comp(node x,node y) { return x.h<y.h; }
16 
17 void solve()
18 {
19     sort(a+1,a+n+1,comp);
20     int ans=0;
21     for1(i,1,n)
22     {
23         for(int k=1;k<a[i].m;k*=2)
24         {
25             for(int j=a[i].h;j>=k*a[i].v;j--)
26             {
27                 dp[j]=max(dp[j],dp[j-k*a[i].v]+k*a[i].v);
28                 ans=max(ans,dp[j]);
29             }
30             a[i].m-=k;
31         }
32         for(int j=a[i].h;j>=a[i].m*a[i].v;j--)
33         {
34             dp[j]=max(dp[j],dp[j-a[i].m*a[i].v]+a[i].m*a[i].v);
35             ans=max(ans,dp[j]);
36         }
37     }
38     printf("%d
",ans);
39 }
40                 
41 void init()
42 {
43     read(n);
44     for1(i,1,n)
45     {
46         read(a[i].v);
47         read(a[i].h);
48         read(a[i].m);
49     }
50 }
51 
52 int main()
53 {
54 #ifndef ONLINE_JUDGE
55     freopen("space.in","r",stdin);
56     freopen("space.out","w",stdout);
57 #endif
58     init();
59     solve();
60 #ifndef ONLINE_JUDGE
61     fclose(stdin);
62     fclose(stdout);
63     system("space.out");
64 #endif
65     return 0;
66 }
View Code
原文地址:https://www.cnblogs.com/Sunnie69/p/5445290.html