题目:给你n个正方体,每个面有一种颜色,他们按照重量递增的方式排列着,现在要求把他们排成一个塔,
每层一个正方体,要求每个正方体上面的正方体的重量全都小于他,还要保证接触的面上的颜色相同,
问最高能摆放多少层,答案不唯一。
分析:dp,动态规划,lis。最大不下降子序列,已经排好序,满足接触的面颜色相同即可。
定义状态:f(i,k)为以第i个方块作为顶时,k面朝上时的最大高度;
转移方程:f(i,k)= max(f(j,f)) { j < i,且相接处的面相同 };
每个方块有6中摆放法式,利用一维数组压缩状态记录前驱,输出路径。
说明:去反面直接异或操作即可,好久没刷题了╮(╯▽╰)╭。
#include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <cmath> using namespace std; int cubes[505][6]; int length[505][6]; int front[3333]; char face[6][7] = {"front", "back", "left", "right", "top", "bottom"}; void output(int space, int n) { if (space) { printf("%d %s\n",n-space/6,face[space%6]); output(front[space], n); } } int main() { int n,t = 0; while (~scanf("%d",&n) && n) { for (int i = n; i >= 1; -- i) { for (int j = 0; j < 6; ++ j) { scanf("%d",&cubes[i][j]); } } int max = 0,space = 0; for (int i = 1; i <= n; ++ i) { for (int k = 0; k < 6; ++ k) { length[i][k] = 1; front[6*i+k] = 0; for (int j = 1; j < i; ++ j) { for (int f = 0; f < 6; ++ f) { if (cubes[j][f] == cubes[i][k^1] && length[j][f] >= length[i][k]) { length[i][k] = length[j][f]+1; front[6*i+k] = 6*j+f; } } } if (max < length[i][k]) { max = length[i][k]; space = 6*i+k; } } } if (t ++) printf("\n"); printf("Case #%d\n",t); printf("%d\n",max); output(space, n+1); } return 0; }
时间: 2024-11-09 00:50:55