/**
* 简单DP,不过要注意记录起始答案。
* 思路: 这题有点像另外一个入门dp题(题意大概是):
* 给你个三角形样式的各数,从最上面的顶点开始一直到最底层,
* 选条路线使得该路线经过的数之和最大。
* 其实这题也差不多,从最底层的方块先放好,然后一层一层往上,
* 只不过这题有可能“断层”(也就是不选某个方块)
* 现在dp过程就是i从 i = n -> 1 这样,
* dp[i][j] 表示的是第i个方块如果是j面朝上,则其下方能摆放的最大方块数。
*/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <algorithm>
#define DEBUG 0
#define INF 0x7fffffff
#define MAXS 505
#define LL long long
using namespace std;
int ans[MAXS][7], next[MAXS][7], dp[MAXS][7], cubes[MAXS][7];
char face[7][10] = {"", "front", "back", "left", "right", "top", "bottom"};
int maxAns, start, startFace;
int anti_face(int x) {
if(x % 2) return x + 1;
else return x - 1;
}
void dpf(int n) {
/** 1WA 忘记初始化maxAns. */
maxAns = 0;
memset(dp, 0, sizeof(dp));
memset(ans, 0, sizeof(ans));
for(int i = 1; i <= 6; i ++)
dp[n][i] = 1;
for(int i = n - 1; i > 0; i --) {
for(int j = i + 1; j <= n; j ++) {
for(int k = 1; k <= 6; k ++) {
int anti = anti_face(k);
for(int l = 1; l <= 6; l ++) {
if(cubes[i][k] != cubes[j][l]) continue;
if(dp[j][l] > dp[i][anti]) {
dp[i][anti] = dp[j][l];
next[i][anti] = j;
ans[i][anti] = l;
}
}
}
}
for(int k = 1; k <= 6; k ++) {
if(++dp[i][k] > maxAns) {
maxAns = dp[i][k];
startFace = k; start = i;
}
}
}
}
int main()
{
int n, curCase = 1;
while(scanf("%d", &n), n) {
if(curCase != 1) printf("\n");
for(int i = 1; i <= n; i ++) {
for(int j = 1; j <= 6; j ++)
scanf("%d", &cubes[i][j]);
}
dpf(n);
printf("Case #%d\n%d\n", curCase ++, dp[start][startFace]);
int cur = start, curFace = startFace;
for(int i = 1; i <= dp[start][startFace]; i ++) {
int t = cur;
printf("%d %s\n", cur, face[curFace]);
cur = next[t][curFace];
curFace = ans[t][curFace];
}
}
return 0;
}
UVa 10051 Tower of Cubes DP 简单动态规划题
最新推荐文章于 2015-01-07 16:03:06 发布