1. 程式人生 > >UVA The Tower of Babylon

UVA The Tower of Babylon

stream min .org pri for each wrap ada html_ ott

The Tower of Babylon

Perhaps you have heard of the legend of the Tower of Babylon. Nowadays many details of this tale have been forgotten. So now, in line with the educational nature of this contest, we will tell you the whole story:

The babylonians had n types of blocks, and an unlimited supply of blocks of each type. Each type-i

block was a rectangular solid with linear dimensions 技術分享 . A block could be reoriented so that any two of its three dimensions determined the dimensions of the base and the other dimension was the height. They wanted to construct the tallest tower possible by stacking blocks. The problem was that, in building a tower, one block could only be placed on top of another block as long as the two base dimensions of the upper block were both strictly smaller than the corresponding base dimensions of the lower block. This meant, for example, that blocks oriented to have equal-sized bases couldn‘t be stacked.

Your job is to write a program that determines the height of the tallest tower the babylonians can build with a given set of blocks.

Input and Output

The input file will contain one or more test cases. The first line of each test case contains an integer n, representing the number of different blocks in the following data set. The maximum value for n

is 30. Each of the next n lines contains three integers representing the values 技術分享 , 技術分享 and 技術分享 .

Input is terminated by a value of zero (0) for n.

For each test case, print one line containing the case number (they are numbered sequentially starting from 1) and the height of the tallest possible tower in the format "Case case: maximum height = height"

Sample Input

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

Sample Output

Case 1: maximum height = 40
Case 2: maximum height = 21
Case 3: maximum height = 28
Case 4: maximum height = 342

題意:

或許你曾聽過巴比倫塔的傳說,現在這個故事的許多細節已經被遺忘了。現在,我們要告訴你整個故事:

巴比倫人有n種不同的積木,每種積木都是實心長方體,且數目都是無限的。第i種積木的長寬高分別為{ x i , y i , z i }。積木可以被旋轉,所以前面的長寬高是可以互相換的。也就是其中2個組成底部的長方形,剩下的一個為高度。巴比倫人想要盡可能的用積木來堆高塔,但是兩塊積木要疊在一起是有條件的:只有在第一塊積木的底部2個邊均小於第二塊積木的底部相對的2個邊時,第一塊積木才可以疊在第二塊積木上方。例如:底部為3x8的積木可以放在底部為4x10的積木上,但是無法放在底部為6x7的積木上。

給你一些積木的資料,你的任務是寫一個程式算出可以堆出的塔最高是多少。

簡單題意:

有n(n<=30)種立方體,每種都有無窮多個。要求選一些立方體摞成一根盡量高的柱子(可以自行選擇那條邊作為高),使得每個立方體的底面長寬分別嚴格小於它下方立方體的底面長寬

思路:其實題目中的每種立方體都有無限個是沒大有的,因為你很容易就可以想到,每個立方體最多用三次。那麽我們就可以把每個立方體分成三個高不同的立方體。如果一個立方體能放在另一個立方體上面,就在這兩個立方體之間連邊(有向邊,底面小的向底面大的連邊),這樣就形成了一張有向圖,最後,在圖上搜索最長路作DAG上的最長路即可。

吐槽:其實這個題目仔細想想還是挺水的,但可能是我太菜的原因,竟然做了辣麽久┭┮﹏┭┮

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,tot,num,ans,g[40*3][40*3],f[40*3];
struct nond{
    int x,y,z;
}v[40*3];
void pre(){
    for(int i=1;i<=3*n;i++)
        for(int j=1;j<=3*n;j++){
            if(i==j)    continue;
            if(v[i].x<v[j].x&&v[i].y<v[j].y||v[i].x<v[j].y&&v[i].y<v[j].x)
                g[i][j]=1;
        }
}
int dfs(int x){
    if(f[x]!=-1)    return f[x];
    f[x]=v[x].z;
    for(int i=1;i<=3*n;i++)
        if(g[x][i])
            f[x]=max(f[x],dfs(i)+v[x].z);
    return f[x];
}
int main(){
    while(scanf("%d",&n)&&n!=0){
        num++;ans=0;tot=0;
        memset(v,0,sizeof(v));
        memset(g,0,sizeof(g));
        memset(f,-1,sizeof(f));
        for(int i=1;i<=n;i++){
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            v[++tot].x=x;v[tot].y=y;v[tot].z=z;
            v[++tot].x=y;v[tot].y=z;v[tot].z=x;
            v[++tot].x=z;v[tot].y=x;v[tot].z=y;
        }
        pre();
        for(int i=1;i<=3*n;i++)
            ans=max(ans,dfs(i));
        cout<<"Case "<<num<<": maximum height = ";
        cout<<ans<<endl;
    }
}

UVA The Tower of Babylon