UVa 437 (变形的LIS) The Tower of Babylon

题意:

有n种类型的长方体,每种长方体的个数都有无限个。当一个长方体的长和宽分别严格小于另一个长方体的长和宽的时候,才可以把这个放到第二个上面去。输出这n种长方体能组成的最大长度。

分析:

虽说每种都有无限个,可每种长方体一共的“姿态”最多也只有三种,将它们三个边长分别作为高。然后按照底面排序,就转化为最大上升子列的问题。

代码中采用了“人人为我”的方法。

 

 1 //#define LOCAL
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <cstdio>
 5 #include <cstring>
 6 using namespace std;
 7 
 8 const int maxn = 100;
 9 struct Cube
10 {
11     int x, y, z;
12     bool operator< (const Cube& a) const
13     { return x < a.x || (x == a.x && y < a.y); }
14 }cubes[maxn];
15 int size[3], dp[maxn];
16 
17 bool check(int a, int b)
18 {
19     return (cubes[a].x < cubes[b].x && cubes[a].y < cubes[b].y);
20 }
21 
22 int main(void)
23 {
24     #ifdef LOCAL
25         freopen("437in.txt", "r", stdin);
26     #endif
27 
28     int n, kase = 0;
29     while(scanf("%d",&n) == 1 && n)
30     {
31         for(int i = 0; i < n; ++i)
32         {
33             for(int j = 0; j < 3; ++j)    scanf("%d", &size[j]);
34             sort(size, size + 3);
35             cubes[i*3].x = size[0], cubes[i*3].y = size[1], cubes[i*3].z = size[2];
36             cubes[i*3+1].x = size[0], cubes[i*3+1].y = size[2], cubes[i*3+1].z = size[1];
37             cubes[i*3+2].x = size[1], cubes[i*3+2].y = size[2], cubes[i*3+2].z = size[0];
38         }
39         n *= 3;
40         sort(cubes, cubes + n);
41         memset(dp, 0, sizeof(dp));
42         for(int i = 0; i < n; ++i)    dp[i] = cubes[i].z;
43         for(int i = 1; i < n; ++i)
44             for(int j = 0; j < i; ++j)
45                 if(check(j, i))    dp[i] = max(dp[i], cubes[i].z + dp[j]);
46         int ans = 0;
47         for(int i = 0; i < n; ++i)    ans = max(ans, dp[i]);
48         printf("Case %d: maximum height = %d\n", ++kase, ans);
49     }
50 
51     return 0;
52 }
代码君

 

posted @ 2014-09-28 22:46  AOQNRMGYXLMV  阅读(234)  评论(0编辑  收藏  举报