PKU&EOJ:Space Elevator

Space Elevator
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 3691 Accepted: 1642

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

37 40 35 23 82 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.
___________________________________________________________________________________________________
题解:
显然是背包问题。
————
可是我一直纠结在背包的容量到底是什么上。我的想法是,背包容量是物品的个数,然后背包的价值就是能达到的最大高度,即DP[I][J]表示前I个物品,一共用了J个物品,能达到的最大高度。后来发现这个状态表示的方法显然是有问题的,文中有限制条件,第I种物品,它的高度适中不能超过A[I],那么就会发生这种情况:DP[I-1][J]+H[I]>A[I],那么这个高度就达不到,但实际上前I-1种物品选了J个,有一种情况恰能达到A[I]-H[I]的高度,这样再选第I种物品,A[I]的高度就能达到了。可是A[I]-H[I]这个高度不是DP[I-1][J]里面的最大值,所以不会被记录下来。
————
正解:DP[I]表示高度为I能不能达到,实际上这题中,背包的容量和价值是同一个东西,即高度。这是一个多重背包问题,有O(N*V*C)的解法和O(V*Σlog C[i])的解法。另外,EOJ的评测机果然比PKU的慢很多。
O(N*V*C)
代码
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<memory.h>
4  struct node
5 {
6 int h,a;
7 }d[4001];
8  int i,j,max,t,x,y,z,n;
9  int dp[40001];
10  int cmp(const void *a,const void *b)
11 {
12 struct node *x=(struct node *)a;
13 struct node *y=(struct node *)b;
14 return ((x->a>y->a)?1:-1);
15 }
16  int main()
17 {
18 scanf("%d",&n);
19 t=0;
20 for (i=1;i<=n;i++)
21 {
22 scanf("%d%d%d",&x,&y,&z);
23 for (j=1;j<=z;j++)
24 {
25 d[++t].h=x;
26 d[t].a=y;
27 }
28 }
29 qsort(&d[1],t,sizeof(d[1]),cmp);
30 memset(dp,0,sizeof(dp));
31 dp[0]=1;
32 max=0;
33 for (i=1;i<=t;i++)
34 for (j=max;j>=0;j--)
35 if (dp[j]==1&&j+d[i].h<=d[i].a)
36 {
37 dp[j+d[i].h]=1;
38 if (j+d[i].h>max) max=j+d[i].h;
39 }
40 printf("%d\n",max);
41 return 0;
42 }
43

 

O(V*Σlog C[i])

 

代码
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<memory.h>
4  struct node
5 {
6 int h,a;
7 }d[4001];
8  int i,j,max,t,x,y,z,n,rest,base;
9  int dp[40001];
10  int cmp(const void *a,const void *b)
11 {
12 struct node *x=(struct node *)a;
13 struct node *y=(struct node *)b;
14 return ((x->a>y->a)?1:-1);
15 }
16  int main()
17 {
18 scanf("%d",&n);
19 t=0;
20 for (i=1;i<=n;i++)
21 {
22 scanf("%d%d%d",&x,&y,&z);
23 rest=z;
24 base=1;
25 while (base<=rest)
26 {
27 d[++t].h=x*base;
28 d[t].a=y;
29 rest-=base;
30 base*=2;
31 }
32 if (rest>0)
33 {
34 d[++t].h=x*rest;
35 d[t].a=y;
36 }
37 }
38 qsort(&d[1],t,sizeof(d[1]),cmp);
39 memset(dp,0,sizeof(dp));
40 dp[0]=1;
41 max=0;
42 for (i=1;i<=t;i++)
43 for (j=max;j>=0;j--)
44 if (dp[j]==1&&j+d[i].h<=d[i].a)
45 {
46 dp[j+d[i].h]=1;
47 if (j+d[i].h>max) max=j+d[i].h;
48 }
49 printf("%d\n",max);
50 return 0;
51 }
52

 

posted on 2010-07-29 14:25  风也轻云也淡  阅读(201)  评论(0编辑  收藏  举报