传送门

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. 怎样安装Android Studio

    在浏览器地址栏输入 http://www.android-studio.org/ 打开Android Studio中文社区, 下载安装包: 这里需要注意的是SDK的目录, 我没有选择默认的目录, 而是 ...

  2. Maxscript-获取选中文件

    Maxscript - 获取选中文件 使用 .Net 的方法弹出窗口选择文件,并范围所有选中文件的路径“” Fn Fun_GetFilePaths strTitle strFilter = ( dia ...

  3. Elasticsearch 相同内容文档,不同score(评分)的奇怪问题

    原文:http://stackoverflow.com/questions/14580752/elasticsearch-gives-different-scores-for-same-documen ...

  4. oracle常用函数总结

    Oracle常用函数总结 ---oracle常用函数-----一.数值型常用函数----取整数--select floor(10.1) from dual;--将n四舍五入,保留小数点后m位(默认情况 ...

  5. 迭代器类型:iterator & const_iterator

    vector<int> ivec{1, 3, 4, 1, 3, 4}; vector<int>::iterator iter; // iter能读写vector<int& ...

  6. 给你的WP应用加上帮助文档

    背景 这算是Windows Phone编程回顾续篇, 接着给大家聊WP开发经验. 在开发了数个WP应用并发布后, 陆续收到很多反馈邮件, 其中接近一半的邮件是在问"某某功能有没有?" ...

  7. 2017秋软工1 - 本周PSP

    1.本周PSP 2. 本周PSP饼状图 3. 本周进度条 4. 累计进度图

  8. 20145214 《Java程序设计》第8周学习总结

    20145214 <Java程序设计>第8周学习总结 教材学习内容总结 日志API 使用日志的起点是Logger类,Logger类的构造函数标示为protected,不是java.util ...

  9. C#2d命令行小游戏

    [ 星 辰 · 第 二 条 约 定 ] 要求 空地:空格 | 边界/墙:'█' | 人物:'♜' 实现人物的上下左右移动 记录关系图.流程图.设计过程遇到的问题及解决 项目压缩包 [项目源码](htt ...

  10. <Effective C++>读书摘要--Ctors、Dtors and Assignment Operators<一>

    <Item 5> Know what functions C++ silently writes and calls 1.If you don't declare them yoursel ...