The Tower of Babylon 巴比伦塔 UVA - 437

The Tower of Babylon
紫书P269
有n种立方体,每种都有无穷多个。要求选一些立方体落成一根尽量高的柱子(可以自行选择哪一条边作为高),是的每个立方体的底面长款分别严格小于它下方立方体的底面长宽。

立方体可以旋转,所以一种立方体可以看成三个固定摆法的立方体,即为3*n种立方体中求最长路。

#include<iostream>
#include<algorithm>
#include<cstring>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn = 34;
struct node
{
	int a, b, h;
}block[maxn*3];
bool able[maxn*3][maxn*3];//i的k种方法能不能放在j的l种方法上
int n;
bool can_put(int x,int y)
{
	if (block[x].a < block[y].a&&block[x].b < block[y].b)
		return true;
	if (block[x].b < block[y].a&&block[x].a < block[y].b)
		return true;
	return false;
}
int dp[maxn*3];//用第i个木块当顶的最大高度
int dfs(int x)
{
	if (x == 0)
		return 0;
	if (dp[x] != 0)
		return dp[x];
	//int k = x / 3;//每种方块有无限个
	//int self[3] = { k * 3 + 1,k * 3 + 2,k * 3 + 3 };
	int temp = block[x].h;
	for (int i = 1; i <= 3 * n; i++)
	{
		//if (i == self[0] || i == self[1] || i == self[2])
		//	continue;
		if (able[x][i])
		{
			temp = max(temp, dfs(i) + block[x].h);
		}
	}
	return dp[x] = temp;
}
int main()
{
	int cnt = 1;
	while (scanf("%d", &n)!=EOF)
	{
		if (n == 0)
			return 0;
		for (int i = 1; i <= n; i++)
		{
			int x, y, z;
			scanf("%d%d%d", &x, &y, &z);
			block[3*i] = { x,y,z };
			block[3*i-1] = { y,z,x };
			block[3*i-2] = { x,z,y };
		}
		for (int i = 1; i <= 3 * n; i++)
		{
			for (int j = 1; j <= 3 * n; j++)
			{
				if (i == j)
					continue;
				able[i][j] = can_put(i, j);
			}
		}
		int ans = 0;
		mem(dp, 0);
		for (int i = 1; i <= 3*n; i++)
		{
			ans = max(ans, dfs(i));
		}
		printf("Case %d: maximum height = %d\n", cnt++,ans);
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值