zoj 1093 || hdu 1069 Monkey and Banana( Easy DP )

继续水DP。应该第一次就AC的,数组开小了,悲剧啊。

摞砖头,砖头的长宽高可以互换。等于说,每个砖头有三种情况,三个底,三个高。

题目要求,砖头可以无限取,但是上面的砖头的底面必须完全包含于下面的砖头的上面。

因为相同长宽的面不可以放一起,所以每种砖头只能取三种情况,也就是三种不同的高。

直接枚举,然后按最小边长排序,然后就和上面那题一样了。

AC搜了下,没啥比较新颖的解法 = =。。而且发现我写的还是比较好看的。。。

#include <queue>
#include <stack>
#include <math.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>
#define MID(x,y) ( ( x + y ) >> 1 )
#define L(x) ( x << 1 )
#define R(x) ( x << 1 | 1 )
#define BUG puts("here!!!")

using namespace std;

const int MAX = 35;
struct BLOCK{ int x,y,h;};
BLOCK b[MAX*3];
int dp[MAX*3];

void B(int x,int y,int h,int &cnt)
{
	b[cnt].x = min(x,y); b[cnt].y = max(x,y); b[cnt++].h = h;
}

bool check(BLOCK a,BLOCK b)
{
	return a.x > b.x && a.y > b.y;
}
bool cmp(BLOCK a,BLOCK b)
{
	if( a.x == b.x )
		return a.y < b.y;
	return a.x < b.x;
}
int main()
{
	int n,x,y,z;
	int ind = 1;
	
	while( ~scanf("%d",&n) && n )
	{
		int cnt = 0;
		for(int i=0; i<n; i++)
		{
			scanf("%d%d%d",&x,&y,&z);
			B(x,y,z,cnt); B(y,z,x,cnt); B(x,z,y,cnt);
		}
		
		sort(b,b+cnt,cmp);
		
		for(int i=0; i<cnt; i++)
			dp[i] = b[i].h;
			
		for(int i=1; i<cnt; i++)
			for(int k=0; k<i; k++)
				if( check(b[i],b[k]) )
					dp[i] = max(dp[i],dp[k]+b[i].h);
		int ans = dp[max_element(dp,dp+cnt) - dp];
		
		printf("Case %d: maximum height = %d\n",ind++,ans);

	}
return 0;
}


你可能感兴趣的:(struct)