一. Vjudge链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19214
二. 题目大意:给出若干个立方体的长、宽、高,要叠出一个高度最高的塔,要求下面的立方体的长宽严格大于上面立方体的长宽,每个立方体有无限个。
三. 思路:对于一个立方体的属性(x,y,h),可将x,y,h分别做一次高,长宽顺序没关系,这样它们就各自只能出现一次。第二次出现的话,肯定不满足严格大于的条件。然后以分解后的每一个做为终点,就是最顶端的那个,进行DFS,设个DP数组记录每个立方体做为终点的最优条件,记忆化搜索。
其实学过图论的同学可以把下面的长方体指向可以放在它上面的长方体,然后求一次最长路就完了。
四. 代码:
#include <iostream> #include <cstdio> #include <queue> #include <cstring> #include <vector> #include <stack> using namespace std; const int MAX_N = 123, INF = 0x3f3f3f3f; struct Cube { int x, y, h; }arr[MAX_N]; int dp[MAX_N], cnt; void init() { cnt = 0; memset(dp, -1, sizeof(dp)); } void addCube(int x, int y, int h) { arr[cnt++] = {x, y, h}; arr[cnt++] = {h, y, x}; arr[cnt++] = {x, h, y}; } bool isOK(int i, int j) { return arr[i].x < arr[j].x && arr[i].y < arr[j].y || arr[i].x < arr[j].y && arr[i].y < arr[j].x ; } int dfs(int cur) { if(dp[cur] != -1) return dp[cur]; dp[cur] = arr[cur].h; for(int i = 0; i < cnt; i++) if(isOK(cur, i)) dp[cur] = max(dp[cur], dfs(i) + arr[cur].h); return dp[cur]; } int main() { //freopen("in.txt", "r", stdin); int i, j, n, x, y, h, kase = 1; while(~scanf("%d", &n) && n){ init(); while(n--){ scanf("%d%d%d", &x, &y, &h); addCube(x, y, h); } int res = 0; for(i = 0; i < cnt; i++) res = max(res, dfs(i)); printf("Case %d: maximum height = %d\n", kase++, res); } return 0; }