uva 437(不用记忆化搜索解)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_39562952/article/details/84942890

思路:放代码上了

代码如下:

/*
最优解是max height
最优子结构是以i方块作为最后一块的最大长度
子问题的最优解是以前1,2,3...i-1个方块作为最后一块的最大长度
显然:最优子结构包含了子问题的最优解 

并且这些子问题的解之间相互独立(其中一个问题的解,不会影响另外一个)

重叠子问题:每次都不用再计算子问题的解,因为这些解都已经保存在了表中 

综上:用dp[i]保存以i方块作为最后一块的最大长度,dp[i]=dp[k](k=1...n && block[i]>block[k]);
ans=max(dp[1...n]);
复杂度(O(n^2)) ;
这题的坑点。。。别的想法都没错,只有一个地方错了,如果是无序的(后面的可能可以放到前面的顶上)
就说明子问题的最优解不是以前1,2,3...i-1个方块作为最后一块的最大长度而是1...n,但是因为是无序的所以
i..n作为最后一块的长度是不可知的,所以会导致错误
如果先按照面积排序,那么后面的方块,就不能放到前面的顶上了 
子问题的最优解是以前1,2,3...i-1个方块作为最后一块的最大长度
如果是用记忆化搜索就不存在这个问题,因为每次调用的值,一定是确定的以i结尾的最大高度 
*/
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int dp[200];
struct node
{
	int x,y,z;
	
}block[200];
bool cmp(node a,node b)
{
	return a.x * a.y<b.x * b.y;
}
int n;
int main()
{
	int Case=1;
	while(scanf("%d",&n),n)
	{
		int num=1;
		while(n--)
		{
			int temp[3];
			for(int i=0;i<3;i++)
			{
				scanf("%d",&temp[i]);
			}
			sort(temp,temp+3);
			do
			{
				block[num].x=temp[0];
				block[num].y=temp[1];
				block[num++].z=temp[2];
			}while(next_permutation(temp,temp+3));		
		}
		sort(block+1,block+num+1,cmp);
		int maxx=0;
		
		for(int i=1;i<num;i++)
		{
			dp[i]=block[i].z; 
			for(int j=1;j<num;j++)
			{
				if(block[i].x>block[j].x && block[i].y>block[j].y)
				{
					dp[i]=max(dp[j]+block[i].z,dp[i]);
				}
			}
			maxx=max(dp[i],maxx);
		}
		printf("Case %d: maximum height = %d\n",Case++,maxx);
	}
	
	
	
	
	
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39562952/article/details/84942890