题目大意:有 n 个正方体,从序号 1~n, 对应的每个立方体的 6 个面分别有它的颜色(用数字给出),现在想要将立方体堆成塔,并且上面的立方体的序号要小于下面立方体的序号,相邻的面颜色必须相同。输出最高值和路径
解题思路:因为立方体可以旋转,所以一个序号的立方体对应这 6 种不同的摆放方式,可以将问题理解成DAG最长路问题,记录路径要开一个 3 维数组, 路径不唯一,随便输出一条。
#include <cstdio> int main() { char S[6][10] = {"front", "left", "top", "back", "right", "bottom"}; int n, T = 0, cube[505][6], next[505][6][2]; while (scanf("%d", &n), n) { for (int i = 0; i < n; i++) for (int j = 0; j < 3; j++) scanf("%d%d", &cube[i][j], &cube[i][j+3]); int x, y, temp, ans = 0, DP[505][6] = {0}; for (int i = n-1; i >= 0; i--) for (int j = 0; j < 6; j++) { int MAX = 0; for (int k = i+1; k < n; k++) for (int l = 0; l < 6; l++) if (cube[i][(j+3)%6] == cube[k][l] && DP[k][l] > MAX) { MAX = DP[k][l]; next[i][j][0] = k; next[i][j][1] = l; } DP[i][j] = MAX + 1; if (DP[i][j] > ans) { ans = DP[i][j]; x = i; y = j; } } printf(T++ ? "\nCase #%d\n%d\n" : "Case #%d\n%d\n", T, ans); while (ans--) { printf("%d %s\n", x + 1, S[y]); temp = next[x][y][0]; y = next[x][y][1]; x = temp; } } return 0; }