又一個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;
}