思路:
每个长方体都有三种放法,将每个长方体的放法都存起来,然后跑一遍如果此长方体u能够放在另一个长方体v的上面,则建一条u->v的边。然后跑一遍记忆化搜索。
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
const int maxn=105;
int n;
int g[maxn][maxn];
struct chan
{
int x,y,z;
}a[maxn];
int dp[maxn][maxn];
bool judge (chan a,chan b)
{
if(a.x<b.x&&a.y<b.y) return true;
if(a.y<b.x&&a.x<b.y) return true;
return false;
}
int Find(int u,int v)
{
int& ans=dp[u][v];
if(ans!=-1) return ans;
for (int i=1;i<=3*n;i++)
{
if(i==v) continue;
if(g[v][i])
{
ans=max(ans,Find(v,i)+a[u].z);
}
}
if(ans==-1) ans=a[u].z+a[v].z;
return ans;
}
int main()
{
int t=0;
while(scanf("%d",&n)&&n)
{
t++;
memset (g,0,sizeof(g));
for (int i=1;i<=3*n;i+=3)
{
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
a[i+1].x=a[i].y;
a[i+1].y=a[i].z;
a[i+1].z=a[i].x;
a[i+2].x=a[i].x;
a[i+2].y=a[i].z;
a[i+2].z=a[i].y;
}
for (int i=1;i<=3*n;i++)
{
for (int j=1;j<=3*n;j++)
{
if(i==j) continue;
if(judge(a[i],a[j]))
{
g[i][j]=1;
}
}
}
memset (dp,-1,sizeof(dp));
int ans=-1;
for (int i=1;i<=3*n;i++)
{
for (int j=1;j<=3*n;j++)
{
if(g[i][j])
{
ans=max(ans,Find(i,j));
}
}
}
printf("Case %d: maximum height = %d\n",t,ans);
}
return 0;
}