[简单DP] UVA 10051 Tower of Cubes

DAG上的DP,六个方向,打印不要求字典序,相反方向可以通过异或得到(定义0-5代表题目所说的五个方向);

f[i, p] = 1;

for (k = 1:i-1)

  f[i, p] = max(f[i, p], f[k, q]+1) if (color[i][p^1] == color[k][q])

 1 /*
 2     UVA 10051 - Tower of Cubes
 3 */
 4 # include <cstdio>
 5 # include <cstring>
 6 
 7 # define N 500 + 5
 8 # define F 6
 9 
10 const char s[F][10] = {"front", "back", "left", "right", "top", "bottom"};
11 
12 int n;
13 int a[N][F];
14 int f[N][F];
15 
16 int max(int x, int y)
17 {
18     return x>y ? x:y;
19 }
20 
21 int dp(int i, int p)
22 {
23     int &ans = f[i][p];
24     if (ans > 0) return ans;
25     ans = 1;
26     for (int j = 1; j < i; ++j)
27     for (int q = 0; q < F; ++q)
28         if (a[j][q] == a[i][p^1])
29             ans = max(ans, dp(j, q)+1);
30     return ans;
31 }
32 
33 void print_ans(int i, int p)
34 {
35     for (int j = 1; j < i; ++j)
36     for (int q = 0; q < F; ++q)
37     {
38         if (a[j][q] == a[i][p^1] && f[j][q]+1 == f[i][p])
39         {
40             print_ans(j, q);
41             printf("%d %s\n", j, s[q^1]);
42             j = i+1;
43             break;
44         }
45     }
46 }
47 
48 void init(void)
49 {
50     for (int i = 1; i <= n; ++i)
51     for (int j = 0; j < F; ++j)
52         scanf("%d", &a[i][j]);
53     memset(f, -1, sizeof(f[0])*(n+1));
54 }
55 
56 void solve(int icase)
57 {
58     if (icase != 1) putchar('\n');
59     int ans = 0, ti, tj;
60     printf("Case #%d\n", icase);
61     for (int i = 1; i <= n; ++i)
62     for (int j = 0; j < 6; ++j)
63     {
64         // printf("%d\n", dp(i, j));
65         if (ans < dp(i, j))
66         {
67             ans = f[i][j];
68             ti = i;
69             tj = j;
70         }
71     }
72     printf("%d\n", ans);
73     print_ans(ti, tj);
74     printf("%d %s\n", ti, s[tj^1]);
75 }
76 
77 int main()
78 {    
79     int icase = 0;
80     while (scanf("%d", &n), n)
81     {
82         init();
83         solve(++icase);
84     }
85     
86     return 0;
87 }
原文地址:https://www.cnblogs.com/JMDWQ/p/2621808.html