【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 - ...
随机推荐
- Linux命令应用大词典-第8章 日期和时间
8.1 cal:显示日历信息 8.2 date:显示和设置系统日期和时间 8.3 hwclock:查看和设置硬件时钟 8.4 clock:查看和设置硬件时钟 8.5 clockdiff:主机之间测量时 ...
- 关于javascript的一个小问题,请问有人看出啥问题吗?
最近学习javascript,有一个问题挺奇怪的,先贴出代码: function binarySearch(){ var arr = [0,1,2,3]; var res = actbinarySea ...
- smartgit 使用
合并分支
- C Program进阶-二维数组动态内存开辟
对于二维数组,我们知道可以用Type ArrayName[Row][Colume]的方式来定义,这是一种静态内存开辟的方式,程序在编译的时候就为该数组分配了空间,而且行和列大小也是指定的.这篇文章里我 ...
- wpa_supplicant与kernel交互
wpa_supplicant与kernel交互的操作,一般需要先明确驱动接口,以及用户态和kernel态的接口函数,以此来进行调用操作.这里分为4个步骤讨论. 1.首先需要明确指定的驱动接口.因为有较 ...
- 《剑指Offer》题三十一~题四十
三十一.栈的压入.弹出序列 题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的数字均不相等.例如,序列{1, 2, 3, 4 ,5}是某栈的压栈序列 ...
- Python练习——循环2
1.求1~100之间能被7整除,但不能同时被5整除的所有整数 . for i in range(1,101): if i%7 == 0 and i%5 !=0: print(i) 2.输出“水仙花数” ...
- 百度编辑器ueditor的图片地址修正
我用的百度编辑器为1.4.2的,相对于现在这个时间来说是比较新的.之前去的1.3版的,后来更新到1.4之后出现路径问题.因为今天晚上出现特别奇怪的问题,所以特地又整了一遍,发现这玩意还是得自己弄通了好 ...
- Alpha-1
前言 失心疯病源1 团队代码管理github 站立会议 队名:PMS 530雨勤(组长) 今天完成了那些任务 10:00~13:00 OpenCV环境配置,Matlab工具包下载 15:40~17:1 ...
- iOS单利创建的方法
我们在使用单例的时候有两种方法@synchronized,GCD,往往人们使用@synchronized,但是推荐使用GCD: 第一种(@synchronized): + (id)sharedInst ...