UVa 10051 Tower of Cubes DP 简单动态规划题

/**
*    简单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 简单动态规划题)