UVA 10051
UVA 10051
题意:
你需要用立方体建一座塔,每个立方体都不同的有重量,且六面都有颜色;
要求:
重的立方体不能放在重量轻的立方体上;
每个立方体的底面颜色必须和它下面立方体顶面的颜色相同。
输入:多组输入,0 结束。
第一行给出 n , 表示有 n 个立方体。
接下来 n 行, 每行 6 个数,分别表示立方体前后左右上下的颜色。
立方体的重量按顺序给出,也就是说 立方体1 是最轻的,立方体n 是最重的。
输出:首先输出样例编号Case #x,再输出塔的高度 len,接下来 len 行,每行输出两个数, 立方体的编号和哪一面朝上。相邻两组数据之间有空行。
解题:
每个立方体都有 6 种放置的情况, 把每种的信息(顶部和底部的颜色,哪面朝上)都保存下来,
然后求LIS就可以辣。
需要注意的是LIS是由小到大的,所以保存哪一面向上的时候就要保存底部的颜色了= =
#include <bits/stdc++.h> #define ll long long using namespace std; const int maxn = 3050; const int INF = 0x3f3f3f3f; struct node { int bot, top, wt; string dir; void init(int x, int y, int w, string p) { bot = x, top = y, wt = w; dir = p; } }a[maxn], ans[maxn]; int pre[maxn]; int main() { int n, cas = 1; while (scanf ("%d", &n) != EOF && n) { int f, b, l, r, bt, tp, cnt = 1; for (int i = 1; i <= n; i ++) { scanf ("%d%d%d%d%d%d", &f, &b, &l, &r, &tp, &bt ); a[cnt++].init(f, b, i, "front" ); a[cnt++].init(b, f, i, "back" ); a[cnt++].init(l, r, i, "left" ); a[cnt++].init(r, l, i,"right" ); a[cnt++].init(bt, tp, i, "bottom" ); a[cnt++].init(tp, bt, i, "top" ); } int d[maxn] = {0}, mx = 1, ed = 1; for (int i = 0; i < cnt; i ++) pre[i] = i; for (int i = 1; i < cnt; i++) { d[i] = 1; for (int j = 1; j < i; j ++) { if (a[i].wt > a[j].wt && a[i].bot == a[j].top) { if (d[j] + 1 > d[i]) { d[i] = d[j] + 1; pre[i] = j; if (d[i] > mx) { mx = d[i]; ed = i; } } } } } int c = 0; printf ("Case #%d\n%d\n", cas++, mx); while (ed != pre[ed]) { ans[c++] = a[ed]; ed = pre[ed]; } ans[c] = a[ed]; for (int i = c; i >= 0; i--) cout << ans[i].wt << " " << ans[i].dir << endl; printf ("\n"); } return 0; }