UVA__The Tower of Babylon

来源:互联网 发布:淘宝查卖家电话 编辑:程序博客网 时间:2024/06/04 22:22

题目描述:

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 (xi, yi, zi). 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.

题意大概就是给你n种积木,每种积木都有自己的长宽高,并且都有无限个,而且可以旋转。那么你现在需要将这些积木叠放在一起,叠放的要求是低下积木的长宽必须都大于上面积木的长宽。输入n和n种积木的长宽高,输出最大高度,当n为0输入结束。

样例
input:

110 20 3026 8 105 5 571 1 12 2 23 3 34 4 45 5 56 6 67 7 7531 41 5926 53 5897 93 2384 62 6433 83 270

output:

Case 1: maximum height = 40Case 2: maximum height = 21Case 3: maximum height = 28Case 4: maximum height = 342
简单DP,其实状态转移方程很容易想到,麻烦的是预处理,由于每个积木可以旋转,所以每个积木对应的长宽高可以有6种,我的写法比较粗暴,就是一个一个储存起来,然后直接DP就好了
AC代码:
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<string>#include<stack>#include<queue>#include<algorithm>using namespace std;const int MAXM=1000010;struct block{    int len;    int width;    int height;};int n;struct block b[1010];int dp[1010];bool cmp(block b1,block b2){    return b1.len*b1.width<b2.len*b2.width;}int main(){    int cas=1;    while(scanf("%d",&n)!=EOF)    {        if (n==0) break;        memset(b,0,sizeof(b));        int k=1;        for (int i=1;i<=n;i++)        {            int x,y,z;            scanf("%d%d%d",&x,&y,&z);            b[k].len=x;b[k].width=y;b[k].height=z;k++;            b[k].len=x;b[k].width=z;b[k].height=y;k++;            b[k].len=y;b[k].width=x;b[k].height=z;k++;            b[k].len=y;b[k].width=z;b[k].height=x;k++;            b[k].len=z;b[k].width=x;b[k].height=y;k++;            b[k].len=z;b[k].width=y;b[k].height=x;k++;        }        sort(b+1,b+k,cmp);        memset(dp,0,sizeof(dp));        int maxheight=0;        for (int i=1;i<k;i++)        {            dp[i]=b[i].height;            for (int j=1;j<i;j++)            {                if (b[j].len<b[i].len&&b[j].width<b[i].width)                    dp[i]=max(dp[i],dp[j]+b[i].height);            }            if (dp[i]>maxheight)                maxheight=dp[i];        }        printf("Case %d: maximum height = %d\n",cas,maxheight);        cas++;    }    return 0;}



原创粉丝点击