hdu 1069 Monkey and Banana

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1069


又一个dp的题,题目大意是:给你n个木块,每个木块有长宽高三个属性,每个木块都可以使用无穷多个,

问如果将这些个木块堆起来,能达到的最大高度是多少?(每个木块的长和宽必须均大于下面的那个木块);


首先,由于每个木块可以使用无穷多次,所以,每个木块可以当成三个木块来用,三个木块的高分别为原木块的长,宽,高,所以n个木块就变成了3*n个木块,然后读入数据的时候使每个木块的长均不小于高,然后对3n个木块进行排序;长度大的在前,如果一样 宽度高的在前;


然后定义数组f[i]为最上面一个木块是i号木块时所能达到的最大高度,思路和求最长递增子序列一样;求f[i]时,令j从0

到i-1扫描a[i],(a[i]记录木块的长宽高信息),如果j号木块的长宽均大于i号木块的长宽,则i号可以放在j号的上面;

则f[i]=f[j]+a[i].h;当然最终f[i]的值取满足条件的j中高度最大的那个;


#include <iostream>
#include <cstdlib>
using namespace std;
struct tt
{
	int l;
	int w;
	int h;
}s[10006];
int comp(const void *a,const void *b)
{
	if((*(tt *)a).l>(*(tt *)b).l)
		return -1;
	if((*(tt *)a).l<(*(tt *)b).l)
		return 1;
	if((*(tt *)a).w>(*(tt *)b).w)
		return -1;
	if((*(tt *)a).w<(*(tt *)b).w)
		return 1;
}
int len;
void execute(int fl)
{
	int i,j;
	__int64 f[10006];
	for(i=0;i<len;i++)
		f[i]=s[i].h;
	for(i=0;i<len;i++)
	{
		for(j=0;j<i;j++)
		{
			if(s[i].w<s[j].w&&s[i].l<s[j].l)
			{
				if(f[i]<s[i].h+f[j])
					f[i]=s[i].h+f[j];
			}
		}
	}
	__int64 ans;
	ans=f[0];
	for(i=0;i<len;i++)
		if(ans<f[i])
			ans=f[i];
	printf("Case %d: maximum height = %I64d\n",fl+1,ans);
}
int main()
{
	int n;
	int a,b,c;
	int i;
	int t;
	int fl=0;
	while(cin>>n&&n)
	{	
		len=0;
		for(i=0;i<n;i++)
		{
			cin>>a>>b>>c;
			s[len].l=a;
			s[len].w=b;
			s[len].h=c;
			len++;
			s[len].l=a;
			s[len].w=c;
			s[len].h=b;
			len++;
			s[len].l=c;
			s[len].w=b;
			s[len].h=a;
			len++;
		}
		for(i=0;i<len;i++)
		{
			if(s[i].l<s[i].w)
			{
				t=s[i].l;
				s[i].l=s[i].w;
				s[i].w=t;
			}
		}
		qsort(s,len,sizeof(s[0]),comp);
		execute(fl++);
	}
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章