题目大意
有n种长宽高为x,y,z的砖头,每种都有无数个。
砖头可以用不同姿势的方向来盖。
砖头a以某种姿势可以盖在砖头b上,当且仅当a的底部的长宽都要比b的底部长宽要小。
问最高可以建多高?
思路
对于一个x,y,z砖头,它可以有3种姿势放置。
(前两个为地面,后一个为高)
x, y, z
x, z, y
y, z, x
把每种姿势都记录下来,变成了有3*n种固定姿势的砖头。
然后建图,a[i][j] = true, 表示砖头j可以盖在砖头i上。
然后就是求dag上的最长路了。
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define eps 1e-6
typedef long long LL;
const double pi = acos(-1.0);
const long long mod = 1e9 + 7;
using namespace std;
int a[105][105];
int d[105];
int N;
struct data
{
int x,y,z;
}edge[105];
bool cmp(const data i,const data j)
{
if(i.x == j.x)
{
if(i.y == j.y)
return i.z < j.z;
return i.y < j.y;
}
return i.x < j.x;
}
int fun(int i)
{
int& an = d[i];
if(an > 0)
return an;
an = edge[i].z;
for(int j = 0;j < 3 * N;j++)
if(a[i][j])
an = max(an,fun(j) + edge[i].z);
return an;
}
int main()
{
int cas = 1;
while(cin >> N && N)
{
int b[3];
for(int i = 0;i < N;i++)
{
cin >> b[0] >> b[1] >> b[2];
sort(b,b + 3);
//printf("%d %d %d\n",b[0],b[1],b[2]);
edge[3 * i].x = b[0];
edge[3 * i].y = b[1];
edge[3 * i].z = b[2];
edge[3 * i + 1].x = b[0];
edge[3 * i + 1].y = b[2];
edge[3 * i + 1].z = b[1];
edge[3 * i + 2].x = b[1];
edge[3 * i + 2].y = b[2];
edge[3 * i + 2].z = b[0];
}
sort(edge,edge + 3 * N,cmp);
memset(a,0,sizeof(a));
memset(d,0,sizeof(d));
for(int i = 0;i < 3 * N;i++)
for(int j = 0;j < 3 * N;j++)
if(edge[j].x < edge[i].x && edge[j].y < edge[i].y)
a[i][j] = 1;
int ans = 0;
for(int i = 0;i < 3 * N;i++)
ans = max(fun(i),ans);
printf("Case %d: maximum height = ",cas++);
printf("%d\n",ans);
}
return 0;
}