UVa 103 - Stacking Boxes

  题目大意:矩阵嵌套,不过维数是多维的。有两个个k维的盒子A(a1, a1...ak), B(b1, b2...bk),若能找到(a1...ak)的一个排列使得a< bi,则盒子A可嵌套在盒子B中。给出n个k维的盒子,找出最长的可嵌套的盒子的序列。实际上是DAG上的动态规划问题。首先是判断A能否嵌套在B中,对盒子的k维数进行排序,依次比较即可。然后用d[i]表示以节点i为起点的最长路径的长度,可以得到状态转移方程:d(i) = max{d(j)+1}, (i,j)是图上的一条边。最后就是打印路径,根据转移方程递归打印路径即可。

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4 using namespace std;
 5 #define BOXN 35
 6 #define DIMENSION 12
 7 
 8 int k, n;    // k is the number of boxes, n is the dimensionality
 9 int box[BOXN][DIMENSION], d[BOXN];    // d[i] save the number of nodes in the longest path starting with node i    
10 int G[BOXN][BOXN];
11 
12 bool is_nested(int *box1, int *box2)
13 {
14     // if box1 can be nested in box2, return true; otherwise false
15     for (int i = 0; i < n; i++)
16         if (box1[i] >= box2[i])   return false;
17     return true;
18 }
19 
20 int dp(int i)    // compute d[i]
21 {
22     if (d[i] > 0)   return d[i];
23     d[i] = 1;
24     for (int j = 1; j <= k; j++)
25         if (G[i][j])
26             d[i] = max(d[i], dp(j)+1);
27     return d[i];
28 }
29 
30 void print_path(int i)    // print the longest path starting with node i
31 {
32     printf("%d ", i);
33     for (int j = 1; j <= k; j++)
34         if (G[i][j] && d[i] == d[j]+1)
35         {
36             print_path(j);
37             break;
38         }
39 }
40 
41 int main()
42 {
43 #ifdef LOCAL
44     freopen("in", "r", stdin);
45 #endif
46     while (scanf("%d%d", &k, &n) != EOF)
47     {
48         for (int i = 1; i <= k; i++)
49             for (int j = 0; j < n; j++)
50                 scanf("%d", &box[i][j]);
51         for (int i = 1; i <= k; i++)
52             sort(box[i], box[i]+n);
53         memset(G, 0, sizeof(G));
54         for (int i = 1; i <= k; i++)
55             for (int j = 1; j <= k; j++)
56                 if (is_nested(box[i], box[j]))
57                     G[i][j] = 1;
58         int ans = -1;
59         int start = 0;
60         memset(d, 0, sizeof(d));
61         for (int i = 1; i <= k; i++)
62         {
63             int t = dp(i);
64             if (t > ans)
65             {
66                 ans = t;
67                 start = i;
68             }
69         }
70         printf("%d\n", ans);
71         print_path(start);
72         printf("\n");
73     }
74     return 0;
75 }
76         
View Code

 

posted @ 2013-07-16 12:37  xiaobaibuhei  阅读(204)  评论(0编辑  收藏  举报