1. 程式人生 > >UVa 437 The Tower of Babylon

UVa 437 The Tower of Babylon

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