The Tower of Babylon UVA - 437 多状态 , dp

传送门

题目大意:有n种长方体, 每种有无限个, 要求选一些长方体,摞在一起尽量高,要求上面立方体的长和宽严格小于下面的长方体,每个长方体可以旋转,即每个边都可以做高。

解题思路:每个长方体都有三种状态,即三个楞分别为高的状态,d数组保存每个长方体不同状态时在至最低部能摞最高的高度。记忆化搜索即可,用了一个小技巧,即d(a,b)表示第a个长方体第b条楞为高的状态,用get函数即可求出长和宽。


AC代码

#include 
#include 
#include 
#include 
#include 

using namespace std;

int block[35][3];
int d[35][3];
int n;
void get(int *v1, int a, int b)
{
	int v = 0;
	for(int i=0; i<3; i++)
		if(i != b) v1[v++] = block[a][i];//获得除高以外的两条楞当作宽和长
}


int dp(int a, int b)
{
	if(d[a][b] >= 0) return d[a][b];//已经搜索过
	int cur = 0;
	int v1[2], v2[2];
	get(v1, a, b);
	for(int i=0; i < n; i++)
	{
		for(int j=0; j<3; j++)
		{
			get(v2, i, j);
			if(v1[0] > v2[0] && v1[1] > v2[1])
				cur = max(cur, dp(i, j));
		}
	}
	return d[a][b] = cur+block[a][b];
}


int main()
{
	int Case = 0;
	while(~scanf("%d", &n) && n)
	{
		int ans = 0;
		for(int i=0; i


你可能感兴趣的:(动态规划——其他,算法竞赛入门经典——训练指南)