codeforce_exercise_r6

The Tower of Babylon(UVa-437) :

问题描述

题目简述

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.

输入/输出格式

输入格式:
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 xi, yi and zi.
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

样例

输入样例:
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动态规划练习题。这个题和嵌套矩形问题的区别在于立方体是三维的,x,y,z三个变量都可以作为高度值。因此,一种立方体都对应有3种用法(即使长宽高中有相等的情况,也可以这样算)。而由于每种立方体都是无限的,因此,可以将每一种立方体分开成为3类,分别看成3种立方体。这样就可以避免立方体的旋转问题。定义dp(i)为第i种立方体作为低能够达到的最大高度。最终结果为dp的最大值。
另外就是建图和立方体的存储。在存储的时候,可以对长,宽排序,使得每个立方体的长>宽,这样在判断叠加的时候的条件就可以适当简化了。

参考代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;

const int inf=-1000001;

class cube
{
public:
	int length;
	int width;
	int height;
	cube(int x,int y,int z)
	{
		length=max(x,y);
		width=min(x,y);
		height=z;
	}
	bool operator <(const cube& c) const
	{
		return (length<c.length&&width<c.width);
	}
};

int g[100][100];
int h[100];
vector<cube> cubes;
int n;

void init()
{
	memset(g,0,sizeof(g));
	memset(h,inf,sizeof(h));
	cubes.clear();
}

void addedge()
{
	for(int i=0;i<cubes.size();i++)
	{
		for(int j=0;j<cubes.size();j++)
		{
			if(cubes[j]<cubes[i]) g[i][j]=1;
		}
	}
}

int dp(int i)
{
	int& ans=h[i];
	if(ans>0) return ans;
	ans=cubes[i].height;
	for(int j=0;j<cubes.size();j++)
	{
		if(g[i][j]==1)
		{
			ans=max(ans,cubes[i].height+dp(j));
		}
	}
	return ans;
}

int find_max()
{
	int height=-1;
	for(int i=0;i<cubes.size();i++)
	{
		height=max(height,h[i]);
	}
	return height;
}

int main()
{
	int cnt=0;
	while(scanf("%d",&n)==1&&n!=0)
	{
		init();
		int x,y,z;
		for(int i=1;i<=n;i++)
		{
			scanf("%d %d %d",&x,&y,&z);
		    cube c1(x,y,z);
		    cubes.push_back(c1);
		    cube c2(x,z,y);
		    cubes.push_back(c2);
		    cube c3(y,z,x);
		    cubes.push_back(c3);
		}
		addedge();
		for(int i=0;i<cubes.size();i++)
		{
			dp(i);
		}
		printf("Case %d: maximum height = %d\n",++cnt,find_max());
	}
	return 0;
}

心得体会

一个DAG动态规划的模板题。总的来说比较常规,建图和立方体的分开存储需要想一段时间,但总体来说还是比较简单的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值