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;
}


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

汉诺塔(Tower of Hanoi)问题的求解——利用栈与递归

汉诺塔(Tower of Hanoi)问题的求解——利用栈与递归 1. 汉诺塔问题的提法 汉诺塔问题是使用递归解决问题的经典范例。 传说婆罗门庙里有一个塔台,台上有3根标号为A、B、C的用钻石做成...
  • cainv89
  • cainv89
  • 2016年05月22日 23:32
  • 6433

Hanoi Tower问题分析

前言 回家休息第3天了,状态一直不是太好,主要是要补牙,检查身体,见同学见亲戚,心里又着急校招,难得能腾出时间来好好思考,这里也是看,看到了汉诺塔问题,这里记录一下 思路分析 汉诺塔是递归的经典题...
  • zinss26914
  • zinss26914
  • 2013年08月07日 23:21
  • 1916

PHP递归创建目录(伪原创)

AlienTech for better life!~
  • twlkyao
  • twlkyao
  • 2014年01月03日 23:03
  • 2084

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

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

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

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

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

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

uva--437The Tower of Babylon+dp

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

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

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

UVA 437 The Tower of Babylon | dp

题意: 给你无限个
  • u011580493
  • u011580493
  • 2014年07月23日 09:28
  • 255

UVA 437 The Tower of Babylon - 简单dp

题目描述](http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19214)分析:因为每种都有无穷多个,所以可以将每个立方体拆成三个...
  • yuanxinyu402
  • yuanxinyu402
  • 2016年03月26日 15:23
  • 179
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:437 - The Tower of Babylon(记录结果再利用DP)
举报原因:
原因补充:

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