题目链接:http://fastvj.rainng.com/contest/306591#problem/B
题目大意:
有n(n≤30)种立方体,每种都有无穷多个。要求选一些立方体摞成一根尽量高的柱子 (可以自行选择哪一条边作为高),使得每个立方体的底面长宽分别严格小于它下方立方体
的底面长宽。
把一个立方体分成三个点,底不同,点权=高,根据堆积的条件建图。DGA上跑最长链。
#include<bits/stdc++.h>
#define LL long long
using namespace std;
struct node
{
int x, y, z;
node()
{
}
node(int a, int b, int c)
{
x=a, y=b, z=c;
}
}a[200];
int tot;
vector<int> e[500];
int dp[200];
int dfs(int u)//记忆化搜索
{
if(dp[u])
{
return dp[u];
}
for(int i=0;i<e[u].size();i++)
{
int v=e[u][i];
dp[u]=max(dfs(v), dp[u]);
}
dp[u]+=a[u].z;
return dp[u];
}
int main()
{
int n, CUT=1;
while(scanf("%d",&n),n)
{
tot=0;
int x, y, z;
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&x,&y,&z);
a[++tot]={x, y, z};
a[++tot]={x, z, y};
a[++tot]={y, z, x};
}
for(int i=1;i<=3*n;i++)
{
e[i].clear();
dp[i]=0;
}
for(int i=1;i<=tot;i++)
{
for(int j=1;j<=tot;j++)
{
if(a[i].x>a[j].x&&a[i].y>a[j].y||a[i].y>a[j].x&&a[i].x>a[j].y)//如果能够堆积
{
e[i].push_back(j);
}
}
}
int MAX=0;
for(int i=1;i<=tot;i++)
{
dp[i]=dfs(i);
MAX=max(MAX, dp[i]);
}
printf("Case %d: maximum height = %d\n",CUT++,MAX);
}
return 0;
}