【DP】【Uva437】UVA437 The Tower of Babylon
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的更多相关文章
- T2980 LR棋盘【Dp+空间/时间优化】
Online Judge:未知 Label:Dp+滚动+前缀和优化 题目描述 有一个长度为1*n的棋盘,有一些棋子在上面,标记为L和R. 每次操作可以把标记为L的棋子,向左移动一格,把标记为R的棋子, ...
- 【10.3校内测试【国庆七天乐!】】【DP+组合数学/容斥】【spfa多起点多终点+二进制分类】
最开始想的暴力DP是把天数作为一个维度所以怎么都没有办法优化,矩阵快速幂也是$O(n^3)$会爆炸. 但是没有想到另一个转移方程:定义$f[i][j]$表示每天都有值的$i$天,共消费出总值$j$的方 ...
- 【DP+树状数组】BZOJ1264-[AHOI2006]基因匹配Match
[题目大意] 给定n个数和两个长度为n*5的序列,两个序列中的数均有1..n组成,且1..n中每个数恰好出现5次,求两个序列的LCS. [思路] 预处理每个数字在a[i]中出现的五个位置.f[i]示以 ...
- BZOJ1079 [SCOI2008]着色方案 【dp记忆化搜索】
题目 有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块. 所有油漆刚好足够涂满所有木块,即c1+c2+-+ck=n.相邻两个木块涂相同色显得很难看 ...
- 【DP|多重背包可行性】POJ-1014 Dividing
Dividing Time Limit: 1000MS Memory Limit: 10000K Description Marsha and Bill own a collection of mar ...
- COGS 862. 二进制数01串【dp+经典二分+字符串】
862. 二进制数01串 ★ 输入文件:kimbits.in 输出文件:kimbits.out 简单对比 时间限制:1 s 内存限制:128 MB USACO/kimbits(译 by ...
- CodeForces - 597C Subsequences 【DP + 树状数组】
题目链接 http://codeforces.com/problemset/problem/597/C 题意 给出一个n 一个 k 求 n 个数中 长度为k的上升子序列 有多少个 思路 刚开始就是想用 ...
- hihocoder1475 数组分拆【DP+前缀和优化】
思路: DP[ i ] 代表以 i 结尾的方案数. dp[i] += sum[i] - sum[j - 1] != 0 ? dp[j] : 0 ; 对于100%的数据,满足1<=N<=10 ...
- SPOJ130 【DP·背包选取特性】
题意: 给你n个任务,每个任务有一个起始时间,持续时间,一个权值: 问你怎么分配得到最大值 思路: 数据好大..百度了一发意识到自己好菜啊!背包的特性. dp[i]代表前 i 个能构成的最大值. 对于 ...
- lightoj1145 【DP优化求方案】
题意: 有一个k面的骰子,然后问你n个骰子朝上的面数字之和=s的方案: 思路: dp[i][j] 代表 前 i 个骰子组成 j 有多少种方案: 显然 dp[i][j] = dp[i - 1][j - ...
随机推荐
- 怎样安装Android Studio
在浏览器地址栏输入 http://www.android-studio.org/ 打开Android Studio中文社区, 下载安装包: 这里需要注意的是SDK的目录, 我没有选择默认的目录, 而是 ...
- Maxscript-获取选中文件
Maxscript - 获取选中文件 使用 .Net 的方法弹出窗口选择文件,并范围所有选中文件的路径“” Fn Fun_GetFilePaths strTitle strFilter = ( dia ...
- Elasticsearch 相同内容文档,不同score(评分)的奇怪问题
原文:http://stackoverflow.com/questions/14580752/elasticsearch-gives-different-scores-for-same-documen ...
- oracle常用函数总结
Oracle常用函数总结 ---oracle常用函数-----一.数值型常用函数----取整数--select floor(10.1) from dual;--将n四舍五入,保留小数点后m位(默认情况 ...
- 迭代器类型:iterator & const_iterator
vector<int> ivec{1, 3, 4, 1, 3, 4}; vector<int>::iterator iter; // iter能读写vector<int& ...
- 给你的WP应用加上帮助文档
背景 这算是Windows Phone编程回顾续篇, 接着给大家聊WP开发经验. 在开发了数个WP应用并发布后, 陆续收到很多反馈邮件, 其中接近一半的邮件是在问"某某功能有没有?" ...
- 2017秋软工1 - 本周PSP
1.本周PSP 2. 本周PSP饼状图 3. 本周进度条 4. 累计进度图
- 20145214 《Java程序设计》第8周学习总结
20145214 <Java程序设计>第8周学习总结 教材学习内容总结 日志API 使用日志的起点是Logger类,Logger类的构造函数标示为protected,不是java.util ...
- C#2d命令行小游戏
[ 星 辰 · 第 二 条 约 定 ] 要求 空地:空格 | 边界/墙:'█' | 人物:'♜' 实现人物的上下左右移动 记录关系图.流程图.设计过程遇到的问题及解决 项目压缩包 [项目源码](htt ...
- <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 ...