题意:给出一些砖头的长宽高,砖头能叠在另一块上要求它的长宽都小于下面的转头的长宽,问叠起来最高能有多高
分析:设一个砖头的长宽高为x, y, z,那么想当于多了x, z, y 和y, x, z的砖头,如果i能叠在j上,那么g[i][j] = true,转换成DAG问题,dp[i]表示第i块叠在最上部最高的高度
收获:转换成经典模型
代码:
/************************************************ * Author :Running_Time * Created Time :2015-8-28 18:00:01 * File Name :UVA_437.cpp ************************************************/ #include <cstdio> #include <algorithm> #include <iostream> #include <sstream> #include <cstring> #include <cmath> #include <string> #include <vector> #include <queue> #include <deque> #include <stack> #include <list> #include <map> #include <set> #include <bitset> #include <cstdlib> #include <ctime> using namespace std; #define lson l, mid, rt << 1 #define rson mid + 1, r, rt << 1 | 1 typedef long long ll; const int N = 1e2 + 10; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; struct Block { int x, y, z; }b[N]; bool g[N][N]; int dp[N]; int n; int DFS(int u) { if (dp[u] != -1) return dp[u]; dp[u] = b[u].z; for (int i=1; i<=n; ++i) { if (g[u][i]) { dp[u] = max (dp[u], DFS (i) + b[u].z); } } return dp[u]; } bool check(int i, int j) { if (b[i].x < b[j].x && b[i].y < b[j].y) return true; if (b[i].x < b[j].y && b[i].y < b[j].x) return true; return false; } int main(void) { int cas = 0; while (scanf ("%d", &n) == 1) { if (n == 0) break; for (int i=1; i<=n; ++i) { scanf ("%d%d%d", &b[i].x, &b[i].y, &b[i].z); b[n+i].x = b[i].x, b[n+i].y = b[i].z, b[n+i].z = b[i].y; b[2*n+i].x = b[i].y, b[2*n+i].y = b[i].z, b[2*n+i].z = b[i].x; } memset (g, false, sizeof (g)); n *= 3; for (int i=1; i<=n; ++i) { for (int j=i+1; j<=n; ++j) { if (check (i, j)) g[i][j] = true; if (check (j, i)) g[j][i] = true; } } memset (dp, -1, sizeof (dp)); int ans = 0; for (int i=1; i<=n; ++i) { ans = max (ans, DFS (i)); } printf ("Case %d: maximum height = %d\n", ++cas, ans); } return 0; }
时间: 2024-11-05 18:52:47