UVA 437 The Tower of Babylon(DAG)紫书训练

题目链接: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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值