UVa 437 The Tower of Babylon
阿新 • • 發佈:2018-09-24
maximum sca ring 聽說 代碼 case baby inline sort
題目
題目描述
你可能已經聽說過巴比倫塔的傳說。現在這個傳說的許多細節已經被遺忘。所以本著本場比賽的教育性質,我們現在會告訴你整個傳說:
巴比倫人有n種長方形方塊,每種有無限個,第i種方塊的三邊邊長是xi,yi,zi。對於每一個方塊,你可以任意選擇一面作為底,這樣高就隨著確定了。舉個例子,同一種方塊,可能其中一個是豎著放的,一個是側著放的,一個是橫著放的。
他們想要用堆方塊的方式建盡可能高的塔。問題是,只有一個方塊的底的兩條邊嚴格小於另一個方塊的底的兩條邊,這個方塊才能堆在另一個上面。這意味著,一個方塊甚至不能堆在一個底的尺寸與它一樣的方塊的上面。
你的任務是編寫一個程序,計算出這個塔可以建出的最高的高度。v
輸入輸出格式
輸入格式
輸入會包含至少一組數據,每組數據的第一行是一個整數n(n<=30),表示方塊的種類數。 這組數據接下來的n行,每行有三個整數,表示xi,yi,zi。 輸入數據會以0結束。
輸出格式
對於每組數據,輸出一行,其中包含組號(從1開始)和塔最高的高度。按以下格式: Case : maximum height = __
輸入輸出樣例
輸入樣例
1
10 20 30
2
6 8 10
5 5 5
7
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
6 6 6
7 7 7
5
31 41 59
26 53 58
97 93 23
84 62 64
33 83 27
0
輸出樣例
Case 1: maximum height = 40
Case 2: maximum height = 21
Case 3: maximum height = 28
Case 4: maximum height = 342
題解
DAG上求最長路
代碼
#include<cstdio> #include<cstring> #include<algorithm> int n, blocks[35][3], d[35][3]; inline void GetDimensions(int* v, int b, int dim) { int idx = 0; for (register int i(0); i < 3; ++i) if(i != dim) v[idx++] = blocks[b][i]; } inline int dp(const int &i, const int &j) { int& ans = d[i][j]; if(ans > 0) return ans; ans = 0; int v[2], v2[2]; GetDimensions(v, i, j); for (register int a(0); a < n; ++a) for (register int b(0); b < 3; ++b) { GetDimensions(v2, a, b); if(v2[0] < v[0] && v2[1] < v[1]) ans = std::max(ans, dp(a,b)); } ans += blocks[i][j]; return ans; } int main(int argc, char **argv) { register int cases(0); while(scanf("%d", &n) == 1 && n) { for (register int i(0); i < n; ++i) { for (register int j(0); j < 3; ++j) scanf("%d", &blocks[i][j]); std::sort(blocks[i], blocks[i]+3); } memset(d, 0, sizeof(d)); int ans = 0; for (register int i(0); i < n; ++i) for (register int j(0); j < 3; ++j) ans = std::max(ans, dp(i,j)); printf("Case %d: maximum height = %d\n", ++cases, ans); } return 0; }
其它
UVa 437 The Tower of Babylon