题目链接: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;
}