437 - The Tower of Babylon(记录结果再利用DP)

原创 2015年07月10日 20:23:37

最近准备进入动态规划的章节,仔细看了看紫书上对01背包的讲解,感觉很好。。之前看《挑战程序设计竞赛》那本书,就没有讲的那么深刻 。      更加深刻的理解了什么叫记录结果再利用,手工操作了一遍01背包的过程,也有点明白它的状态是如何转移的了,而且那个状态方程所构成的递推关系真的很巧妙 。

言归正传。。这道题就是嵌套矩形问题稍微改了一下,之前的嵌套矩形只需要维护一个状态量就行了,但是这道题是立方体,可以翻转的,所以还要维护一个特征量--高。

由于矩形的嵌套关系,每个状态只会出现一次,所以这么表示是完全可以的(和完全背包不同) 。

细节见代码:

#include<bits/stdc++.h>
using namespace std;
int n,d[35][10],Case = 0;
struct node{
    int v[5];
}a[35];
int dp(int i,int k) {
    int& ans = d[i][k];
    if(ans!=-1) return ans;
    ans = 0;
    for(int j=1;j<=n;j++) {
        if(k==0) { //不要被吓到。。这三部分只有很小的不同,复制就行了
            if((a[j].v[0]>a[i].v[1]&&a[j].v[1]>a[i].v[2])||(a[j].v[1]>a[i].v[1]&&a[j].v[0]>a[i].v[2]))
                ans = max(ans,dp(j,2)+a[j].v[2]);
            if((a[j].v[0]>a[i].v[1]&&a[j].v[2]>a[i].v[2])||(a[j].v[2]>a[i].v[1]&&a[j].v[0]>a[i].v[2]))
                ans = max(ans,dp(j,1)+a[j].v[1]);
            if((a[j].v[1]>a[i].v[1]&&a[j].v[2]>a[i].v[2])||(a[j].v[2]>a[i].v[1]&&a[j].v[1]>a[i].v[2]))
                ans = max(ans,dp(j,0)+a[j].v[0]);
        }
        else if(k==1) {
            if((a[j].v[0]>a[i].v[0]&&a[j].v[1]>a[i].v[2])||(a[j].v[1]>a[i].v[0]&&a[j].v[0]>a[i].v[2]))
                ans = max(ans,dp(j,2)+a[j].v[2]);
            if((a[j].v[0]>a[i].v[0]&&a[j].v[2]>a[i].v[2])||(a[j].v[2]>a[i].v[0]&&a[j].v[0]>a[i].v[2]))
                ans = max(ans,dp(j,1)+a[j].v[1]);
            if((a[j].v[1]>a[i].v[0]&&a[j].v[2]>a[i].v[2])||(a[j].v[2]>a[i].v[0]&&a[j].v[1]>a[i].v[2]))
                ans = max(ans,dp(j,0)+a[j].v[0]);
        }
        else {
            if((a[j].v[0]>a[i].v[0]&&a[j].v[1]>a[i].v[1])||(a[j].v[1]>a[i].v[0]&&a[j].v[0]>a[i].v[1]))
                ans = max(ans,dp(j,2)+a[j].v[2]);
            if((a[j].v[0]>a[i].v[0]&&a[j].v[2]>a[i].v[1])||(a[j].v[2]>a[i].v[0]&&a[j].v[0]>a[i].v[1]))
                ans = max(ans,dp(j,1)+a[j].v[1]);
            if((a[j].v[1]>a[i].v[0]&&a[j].v[2]>a[i].v[1])||(a[j].v[2]>a[i].v[0]&&a[j].v[1]>a[i].v[1]))
                ans = max(ans,dp(j,0)+a[j].v[0]);
        }
    }
    return ans;
}
int main() {
    while(~scanf("%d",&n)&&n) {
        for(int i=1;i<=n;i++) scanf("%d%d%d",&a[i].v[0],&a[i].v[1],&a[i].v[2]);
        int ans = -1;
        for(int i=1;i<=n;i++) {
            for(int j=0;j<=2;j++) {
                memset(d,-1,sizeof(d));//每次都要清空,因为每一次的起点不同,导致结果大不一样
                ans = max(ans,dp(i,j)+a[i].v[j]);
            }
        }
        printf("Case %d: maximum height = %d\n",++Case,ans);
    }
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

uva--437The Tower of Babylon+dp

题意:       给定一些立方体,对于两个立方体,只有其中一个底面两个边都严格小于另一个才可以放在其上面。求可以得到的最大高度。 思路:     一个立方体可以转成6个底面不同的具有不同权...

UVa 437 The Tower of Babylon(DP 最长条件子序列)

 题意  给你n种长方体  每种都有无穷个  当一个长方体的长和宽都小于另一个时  这个长方体可以放在另一个上面  要求输出这样累积起来的最大高度 因为每个长方体都有3种放法  比较不好控制 ...
  • acvay
  • acvay
  • 2014-08-23 10:50
  • 739

UVA 437 The Tower of Babylon | dp

题意: 给你无限个

UVA 437 The Tower of Babylon - 简单dp

题目描述](http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19214)分析:因为每种都有无穷多个,所以可以将每个立方体拆成三个...

UVA 437-The Tower of Babylon(DP)

题目大意:给定n个长方体砖块,每个有长宽高,要求搭成一座塔,对于每个砖块,可以任意旋转,搭在下面的长和宽必须大于上面的。求最高搭多高的塔。 对于每种砖块,转成3种(或2种和1种),它们的高不...

例题9-2 UVA - 437 The Tower of Babylon 巴比伦塔(DGA-DP)(已更新)

大体题意: 给你n种立方体,每种都无限个,要求选择一些立方体使得高度最大,并且满足越靠上的立方体长宽严格小于下面的!每个立方体可以旋转! 输出最大高度! 思路: 可以把立方体的属性存到Node结构体里...

poj 2241 && uva 437 The Tower of Babylon(DP)

题目地址:点击打开链接 思路: 每个砖块可以有三种放置方式,且每种方式至多只会用到一次,所以读入时把每块砖变成 3个不同的就行(长要大于宽),然后对长度进行排序。这样就变成了一个LIS问...

紫书动规 例题9-2 UVA - 437 The Tower of Babylon dp

题目链接:https://vjudge.net/problem/UVA-437题意:题解:dp[i][j]:=考虑到前i个立方体并且第i个立方体以标号为j为高的最大值代码:#include usin...

uva437 poj2241 The Tower of Babylon dp

// 这题开始在算法竞赛入门经典的书上状态表示 // dp[i][j]表示前i个方块以第j条边为高所能得到的最大高度值 // dp[i][j] = max(dp[0...i-1][0,1,2]+blo...

例题9-2 UVa437 The Tower of Babylon(DP:DAG中的最长路)

题意: 看白书 要点: 将x,y,h分别作为高,这样n就转换为3*n种立方体,而且因为每种都有无穷个,所以正好自己叠在自己上的情况也考虑到了,这就转换为前面的嵌套矩形问题,进行一次记忆化搜索即可。 ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)