额。这是一道DAG上的dp题。
题目给出了n种方块,这n种方块都可以翻转,于是总共就有3n种方块,于是可以把问题转化成LIS来处理。我这里偷懒照着白书写了个记忆化搜索。。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
struct T
{
int x;
int y;
int h;
};
T m[100],ck[2000000];
int map[100][100],d[100],lm;
int dp(int n)
{
int i,j;
if (d[n] != m[n].h)
return d[n];
for (i=0; i<lm; i++)
{
if (map[n][i] != 0)
{
j=dp(i)+map[n][i];
d[n]=d[n]>j?d[n]:j;
}
}
return d[n];
}
int main()
{
int n,i,j,t1,t2,t3,ans,prob;
prob=1;
while (1)
{
lm=0;
scanf("%d",&n);
if (n == 0)
break;
while (n--)
{
scanf("%d%d%d",&t1,&t2,&t3);
m[lm].x=t1>t2?t2:t1;
m[lm].y=t1>t2?t1:t2;
m[lm].h=t3;
lm++;
m[lm].x=t3>t2?t2:t3;
m[lm].y=t3>t2?t3:t2;
m[lm].h=t1;
lm++;
m[lm].x=t1>t3?t3:t1;
m[lm].y=t1>t3?t1:t3;
m[lm].h=t2;
lm++;
}
memset(map,0,sizeof(map));
for (i=0; i<lm; i++)
{
d[i]=m[i].h;
for (j=0; j<lm; j++)
{
if (m[i].x > m[j].x && m[i].y > m[j].y)
map[i][j]=m[i].h;
}
}
ans=-1;
for (i=0; i<lm; i++)
{
j=dp(i);
if (j>ans)
ans=j;
}
printf("Case %d: maximum height = %d\n",prob,ans);
/* for (i=0; i<lm; i++)
{
printf("%d %d %d\n",m[i].x,m[i].y,m[i].h);
}
for (i=0; i<lm; i++)
{
for (j=0; j<lm; j++)
{
printf("%d ",map[i][j]);
}
printf("\n");
}*/
prob++;
}
}