题目链接:https://vjudge.net/problem/UVA-437
做题感受:DAG的跟进版本,主要考虑的是如何把状态转移方程表示出来,这道题难在表示,但是实际上又可以不用在表示上困惑,我自己按lrj的方法做了半天没做出来(还是太菜),看别人的方法一下就出来了(自己做的时候甚至开了一个四维数组,还做不出来)。(lrj的方法以后找时间补一下吧)
思路:化立体为平面,把每个x,y,z都分别当做长,宽,高
也就是
xyz
xzy
yzx
yxz
zxy
zyx
这种顺序,(因为实际上自己的情况和自己的情况比较并不可行,因为需要a的长和宽严格大于b的长和宽,而且是a的长度大于b的长度,并且a的宽度大于b的宽度)然后排序并且用DAG模型递推即可,简单方便,就是空间占的稍微大了一点,但并不影响做题。
下面是我的代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
int n;
int dp[35];//表示从该点开始算最多叠到多高
struct lifangti {
int x, y, z;
lifangti(int x = 0, int y = 0, int z = 0):x(x),y(y),z(z){}//构造函数,方便下面多次创建结构体
}a[205];
bool cmp(lifangti a, lifangti b)
{
return a.x * a.y < b.x* b.y;//根据面积排序,方便递推
}
int main()
{
int i, j, case1 = 1;
while (scanf("%d",&n)&&n!=0)
{
memset(dp, 0, sizeof(dp));
for (i = 1; i <= n; i++)
{
cin >>a[6*i-5].x >> a[6 * i - 5].y >> a[6 * i - 5].z;//构造6*n个结构体(输入的时候用a,b,c表示其实更快,下面直接三个字母构造就完成了)
a[6 * i - 4]=lifangti(a[6 * i - 5].x,a[6 * i - 5].z,a[6 * i - 5].y);
a[6 * i - 3]=lifangti(a[6 * i - 5].y, a[6 * i - 5].x, a[6 * i - 5].z);
a[6 * i - 2]=lifangti(a[6 * i - 5].y, a[6 * i - 5].z, a[6 * i - 5].x);
a[6 * i - 1]=lifangti(a[6 * i - 5].z, a[6 * i - 5].x, a[6 * i - 5].y);
a[6 * i ]=lifangti(a[6 * i - 5].z, a[6 * i - 5].y, a[6 * i - 5].x);
}
sort(a+1, a + 6*n+1, cmp);//排序,记得是6*n
int Max = 0;
for (i = 1; i <= 6*n; i++) //记得6*n
{
dp[i] = a[i].z;
for (j = 1; j <i; j++)
{
if (a[i].x > a[j].x && a[i].y > a[j].y)
dp[i] = max(dp[i], dp[j] + a[i].z);//递推
}
if (Max < dp[i])
Max = dp[i];
}
printf("Case %d: maximum height = %d\n", case1++, Max);
}
return 0;
}