传送门

Description

Input

Output

Sample Input


Sample Output

Case : maximum height =
Case : maximum height =
Case : maximum height =
Case : maximum height =

Hint

  n<=30。

Solution

  一眼看出这是个DAG上的DP,一个信息分成三个方块存储。然后开始读入,拓扑,输出,过样例,提交,WA……

   这里的关键是拓扑序应该怎么求。首先我的比较函数写法如下:

inline bool cmp(const Block &a,const Block &b) {
return (a.l1<b.l1&&a.l2<b.l2)||(a.l2<b.l1&&a.l1<b.l2);
}

   然后由于sort的一些问题,这么写会挂掉。hack数据:我丢了……

   然后就来想想这个拓扑怎么求。

   考虑二元组(a,b)表示方块的长和宽,由于长和宽的顺序对放置无影响,所以不妨设a>=b。

   引理:若1能放在2上面,则2不能放在1上面。

    证明:  由题设,a1>a2,b1>b2。

         当2能放在1上面,a2>a1,b2>b1。矛盾。引理得证。

   定理:若a1+b1=a2+b2,则这两个方块不能叠放。

   证明:不妨设a1>=a2。当a1==a2时,b1==b2。又a>b。显然不成立

        当a1>a2,则b1<b2。故不成立。

   定理:当且仅当a1+b1<a2+b2时,方块2可能叠放在1上面。

   证明:已证相等时不成立,现在证明前者大于后者时不成立。

       前者大于后者时,a1+b1>a2+b2。

          当a1<a2,显然b1>b2。不成立。

          当a1>a2,b1>b2,由引理,不成立。

          当a1>a2,b1<b2,显然不成立。

       下面证明可能性

          当a1<a2,b1<b2时,满足原式,可以叠放。

       定理得证。

   由上述定理知,设si=ai+bi,则f[i]只可能由{f[j]|sj<si}转移得到。故将a+b得值设为阶段,进行转移。

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define maxn 100 inline void qr(int &x) {
char ch=getchar();int f=;
while(ch>''||ch<'') {
if(ch=='-') f=-;
ch=getchar();
}
while(ch>=''&&ch<='') x=(x<<)+(x<<)+(ch^),ch=getchar();
x*=f;
return;
} inline int max(const int &a,const int &b) {if(a>b) return a;else return b;}
inline int min(const int &a,const int &b) {if(a<b) return a;else return b;}
inline int abs(const int &x) {if(x>) return x;else return -x;} inline void swap(int &a,int &b) {
int c=a;a=b;b=c;return;
} int n,a,b,c,frog[maxn]; struct Block {
int h,l1,l2;
};
Block block[maxn];int top,cnt,ans; inline void add(int x,int y,int z) {
block[++top].h=x;block[top].l1=y;block[top].l2=z;
if(block[top].l1<block[top].l2) swap(block[top].l2,block[top].l1);
block[++top].h=y;block[top].l1=x;block[top].l2=z;
if(block[top].l1<block[top].l2) swap(block[top].l2,block[top].l1);
block[++top].h=z;block[top].l1=x;block[top].l2=y;
if(block[top].l1<block[top].l2) swap(block[top].l2,block[top].l1);
} void clear() {
std::memset(block,,sizeof block);top=;
std::memset(frog,,sizeof frog);ans=;
} inline bool cmp(const Block &a,const Block &b) {
int sa=a.l1+a.l2,sb=b.l1+b.l2;
return sa<sb;
} inline bool judge(const Block &a,const Block &b) {
return (a.l1<b.l1&&a.l2<b.l2)||(a.l2<b.l1&&a.l1<b.l2);
} int main() {
qr(n);
while(n) {
clear();
for(int i=;i<=n;++i) {
a=b=c=;qr(a);qr(b);qr(c);
add(a,b,c);
}
std::sort(block+,block++top,cmp);
for(int i=;i<=top;++i) {
int &emm=block[i].h;
frog[i]=emm;
for(int j=;j<i;++j) {
if(judge(block[j],block[i])) frog[i]=max(frog[i],frog[j]+emm);
}
ans=max(ans,frog[i]);
}
printf("Case %d: maximum height = %d\n",++cnt,ans);
n=;qr(n);
}
return ;
}

Summary

  1、写完dp和爆搜对拍一下!!!

   2、dp中阶段可能是一个非常难以想象的量,比如二元组的求和,在求拓扑序时可以考虑一些特殊性质。

   3、求拓扑序慎用sort

【DP】【Uva437】UVA437 The Tower of Babylon的更多相关文章

  1. T2980 LR棋盘【Dp+空间/时间优化】

    Online Judge:未知 Label:Dp+滚动+前缀和优化 题目描述 有一个长度为1*n的棋盘,有一些棋子在上面,标记为L和R. 每次操作可以把标记为L的棋子,向左移动一格,把标记为R的棋子, ...

  2. 【10.3校内测试【国庆七天乐!】】【DP+组合数学/容斥】【spfa多起点多终点+二进制分类】

    最开始想的暴力DP是把天数作为一个维度所以怎么都没有办法优化,矩阵快速幂也是$O(n^3)$会爆炸. 但是没有想到另一个转移方程:定义$f[i][j]$表示每天都有值的$i$天,共消费出总值$j$的方 ...

  3. 【DP+树状数组】BZOJ1264-[AHOI2006]基因匹配Match

    [题目大意] 给定n个数和两个长度为n*5的序列,两个序列中的数均有1..n组成,且1..n中每个数恰好出现5次,求两个序列的LCS. [思路] 预处理每个数字在a[i]中出现的五个位置.f[i]示以 ...

  4. BZOJ1079 [SCOI2008]着色方案 【dp记忆化搜索】

    题目 有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块. 所有油漆刚好足够涂满所有木块,即c1+c2+-+ck=n.相邻两个木块涂相同色显得很难看 ...

  5. 【DP|多重背包可行性】POJ-1014 Dividing

    Dividing Time Limit: 1000MS Memory Limit: 10000K Description Marsha and Bill own a collection of mar ...

  6. COGS 862. 二进制数01串【dp+经典二分+字符串】

    862. 二进制数01串 ★   输入文件:kimbits.in   输出文件:kimbits.out   简单对比 时间限制:1 s   内存限制:128 MB USACO/kimbits(译 by ...

  7. CodeForces - 597C Subsequences 【DP + 树状数组】

    题目链接 http://codeforces.com/problemset/problem/597/C 题意 给出一个n 一个 k 求 n 个数中 长度为k的上升子序列 有多少个 思路 刚开始就是想用 ...

  8. hihocoder1475 数组分拆【DP+前缀和优化】

    思路: DP[ i ] 代表以 i 结尾的方案数. dp[i] += sum[i] - sum[j - 1] != 0 ? dp[j] : 0 ; 对于100%的数据,满足1<=N<=10 ...

  9. SPOJ130 【DP·背包选取特性】

    题意: 给你n个任务,每个任务有一个起始时间,持续时间,一个权值: 问你怎么分配得到最大值 思路: 数据好大..百度了一发意识到自己好菜啊!背包的特性. dp[i]代表前 i 个能构成的最大值. 对于 ...

  10. lightoj1145 【DP优化求方案】

    题意: 有一个k面的骰子,然后问你n个骰子朝上的面数字之和=s的方案: 思路: dp[i][j] 代表 前 i 个骰子组成 j 有多少种方案: 显然 dp[i][j] = dp[i - 1][j - ...

随机推荐

  1. Selenium(Python) ddt读取Excel文件数据驱动

    首先, 引入xlrd模块: ExcelDDT.py: import unittestfrom time import sleep from ddt import ddt, datafrom selen ...

  2. Oracle启动与关闭数据库实例

    Oracle数据库启动实例分为3个步骤: 启动实例 加载数据库 打开数据库 通用模式: STARTUP  [ nomount | mount | open | force ]  [resetrict] ...

  3. lintcode101 删除排序数组中的重复数字 II

    删除排序数组中的重复数字 II   跟进“删除重复数字”: 如果可以允许出现两次重复将如何处理? 在:lintcode100删除排序数组中的重复数字 的基础上进行改进. class Solution ...

  4. 【RL系列】Multi-Armed Bandit笔记补充(一)

    在此之前,请先阅读上一篇文章:[RL系列]Multi-Armed Bandit笔记 本篇的主题就如标题所示,只是上一篇文章的补充,主要关注两道来自于Reinforcement Learning: An ...

  5. Solidity中的基本类型转换

    Solidity中的基本类型转换(十四)|入门系列 2017/4/29 posted in Solidity入门系列 点击查看原文,获得优化的排版. 隐式转换 如果一个运算符能支持不同类型.编译器会隐 ...

  6. 【转】AMD 的 CommonJS wrapping

    其实本文的标题应该是「为什么我不推荐使用 AMD 的 Simplified CommonJS wrapping」,但太长了不好看,为了美观我只能砍掉一截. 它是什么? 为了复用已有的 CommonJS ...

  7. Android蓝牙开发浅谈(转)

    http://www.eoeandroid.com/thread-18993-1-1.html 对于一般的软件开发人员来说,蓝牙是很少用到的,尤其是Android的蓝牙开发,国内的例子很少     A ...

  8. HttpServletRequest和HttpServletResponse实例

    先看一下web.xml文件配置: <?xml version="1.0" encoding="UTF-8"?> <web-app versio ...

  9. Java常用类之File类

    File 类: 1. java.io.File 类代表系统文件名(路径名.文件名); 2. File 类常见的构造方法: 2.1. File(String pathname):通过将给定路径名字符串转 ...

  10. OSG学习:响应键盘鼠标示例

    示例功能:示例里面有两个模型,一个是牛,另一个是飞机.鼠标右键时牛和飞机都隐藏,鼠标左键双击时牛和飞机都显示,按键盘上面的LEFT键,显示牛,按键盘上面的RIGHT键显示飞机.其中显示与隐藏节点使用的 ...