1. 程式人生 > >uva 437(不用記憶化搜尋解)

uva 437(不用記憶化搜尋解)

思路:放程式碼上了

程式碼如下:

/*
最優解是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;
}