UVa 10795 - A Different Task 对称, 中间状态, 数位DP 难度: 3
题目
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1736
题意
汉诺塔问题,给定初始状态和最终状态,求最小步数(一定可行)
思路
本来以为是搜索,
如刘书思路。
由于只有三根柱子,假设n-1到i + 1号盘子都已经对齐,对于没有对齐的i号盘子,必要有两根柱子用于转移,一根是现在i所在的柱子,另一根是目的柱子,第三根空闲柱子存放其他无用但是还没对准的小盘子。也即小盘子只能存在空闲柱子上。也即最短路径就是略过已经堆放好的盘子->将无用小盘子堆在空闲柱子上->把最大的没对齐盘子放到应该在的地方这样一个循环。
这样已经能够写出确定性程序,但还存在初始和最终状态都比较复杂的情况。
想到中间状态一定会经过,而忽略掉最后一个还没对齐的最大盘子i的中间状态十分简单,是小盘子[0,...,i-1]在空闲柱子上的简单堆叠,那么可以发现 [0,..., i - 1].终止状态到中间状态的最小步数+ [0,..., i - 1]初始状态到中间状态的最小步数 + 1(移动第i个盘子所需步数) = 总最小步数
而终止状态到中间状态的转换中,移动[0,..., i - 1]到空闲柱子的步数为移动[0, ... , i-2]到新空闲柱子的步数+把[0, ... , i - 2]移回来的步数 + 1(移动i-1),依此类推。(注意有时候不需要移动的情况)
而把[0, ... , i - 2]移回来的步数是2^(i - 2) - 1。
感想
1. 一开始只想到了用搜索暴力做,后来稍微瞄了一眼,也觉得可以用双向bfs来做
2. 之后想到了何为必然出现的状态,也即找到了正确的最短路径,但是还是面临着需要一段段对齐最终状态的问题,代码因此杂乱无章,刘书中提到的将初始和终止状态都转化为清晰简单的中间状态的方法大大减少了实现难度
3. 在实现中一开始不是按照 1 + i-1初始->中间步数 + i-1终止->中间步数来做的,而是按照 i初始->中间步数 + i终止->中间步数,与实际情况不符。
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <tuple>
#include <set>
#include <map>
#include <cassert>
#define LOCAL_DEBUG
using namespace std;
const int MAXN = ;
long long steps[MAXN];
int pegOrg[MAXN];
int pegAim[MAXN]; long long mov(int * pegs, int pos, int desPeg) {
if (pos < ) return ;
if (pegs[pos] == desPeg)return mov(pegs, pos - , desPeg);
return mov(pegs, pos - , - desPeg - pegs[pos]) + steps[pos];
} int main() {
#ifdef LOCAL_DEBUG
freopen("input.txt", "r", stdin);
//freopen("output2.txt", "w", stdout);
#endif // LOCAL_DEBUG
int n;
for (int i = ; i < MAXN; i++) {
steps[i] = 1L << i;
}
for (int ti = ; scanf("%d", &n) == && n; ti++) {
for (int i = ; i < n; i++)scanf("%d", pegOrg + i);
for (int i = ; i < n; i++)scanf("%d", pegAim + i);
long long ans = ;
for (int i = n - ; i >= ; i--) {
if (pegOrg[i] != pegAim[i]) {
ans = mov(pegOrg, i - , - pegAim[i] - pegOrg[i]) + mov(pegAim, i - , - pegAim[i] - pegOrg[i]) + ;
break;
}
}
printf("Case %d: %lld\n", ti, ans);
} return ;
}
UVa 10795 - A Different Task 对称, 中间状态, 数位DP 难度: 3的更多相关文章
- UVa 10795 - A Different Task
题目大意:给出n,表示说有n个大小不同的盘子,然后再给出每个盘子的初始位置和目标位置,要求计算出最少的步数使得每个盘子都移动到它的目标位置. 分析: 首先找最大不在目标柱子上的盘子K,因为如果最大的 ...
- UVA 10795 A Different Task(汉诺塔 递归))
A Different Task The (Three peg) Tower of Hanoi problem is a popular one in computer science. Briefl ...
- UVA 10795 - A Different Task(递归)
A Different Task The (Three peg) Tower of Hanoi problem is a popular one in computer science. Brie ...
- 【汉诺塔问题】UVa 10795 - A Different Task
[经典汉诺塔问题] 汉诺(Hanoi)塔问题:古代有一个梵塔,塔内有三个座A.B.C,A座上有64个盘子,盘子大小不等,大的在下,小的在上.有一个和尚想把这64个盘子从A座移到B座,但每次只能允许移动 ...
- UVA 10795 A Different Task(模拟)
题目链接:https://vjudge.net/problem/UVA-10795 一道比较有思维含量的一道题: 注意一种分治的思想和“除了柱子x和柱子y之外的那个柱子”编号的问题. 首先在初始局面和 ...
- 数位dp总结 之 从入门到模板
转发自WUST_WenHao巨巨的博客 基础篇 数位dp是一种计数用的dp,一般就是要统计一个区间[le,ri]内满足一些条件数的个数.所谓数位dp,字面意思就是在数位上进行dp咯.数位还算是比较好听 ...
- uva 10712 - Count the Numbers(数位dp)
题目链接:uva 10712 - Count the Numbers 题目大意:给出n,a.b.问说在a到b之间有多少个n. 解题思路:数位dp.dp[i][j][x][y]表示第i位为j的时候.x是 ...
- CF431D Random Task 二分+数位dp
One day, after a difficult lecture a diligent student Sasha saw a graffitied desk in the classroom. ...
- uva 10817(数位dp)
uva 10817(数位dp) 某校有m个教师和n个求职者,需讲授s个课程(1<=s<=8, 1<=m<=20, 1<=n<=100).已知每人的工资c(10000 ...
随机推荐
- Java中 Tomcat 是干什么的?
Tomcat是web容器.它的作用稍后给你解释. 你在做web项目时,多数需要http协议,也就是基于请求和响应,比如你在百度输入一行内容搜索, 那么百度服务器如何处理这个请求呢,他需要创建servl ...
- [MySQL]典型的行列转换
列变成行 测试数据库数据样式: 应用的sql语句: SELECT TM,NAME,SUM(GE) AS 'GE',SUM(GD) AS 'GD',SUM(CT) AS 'CT',SUM(NUM) AS ...
- 类似于placehoder效果的图标展示
在做app开发的时候往往会有那个注册登录啊,什么的页面,里面就会包含这那种类似于placeholder的效果的图标,当时我也是和ios和安卓混合开发一款app里面的页面全是我写,最开始就是登陆啊,注册 ...
- Linux 各种软件的安装-Apache + php 篇
mysql装好了,三剑客还差两个 apache就简单多了. yum -y install httpd # 删除默认欢迎页面 rm -f /etc/httpd/conf.d/welcome.conf s ...
- JS 日期比较方法
1.日期参数格式:yyyy-mm-dd // a: 日期a, b: 日期b, flag: 返回的结果 function duibi(a, b,flag) { var arr = a.split(&qu ...
- The MySQL Server
mysqld is the MySQL server. configuring the server. The mysql server, mysqld,has many command option ...
- p1218 Superprime Rib
深搜,添加数字后如果仍为质数,继续递归. #include <iostream> #include <cstdio> #include <cmath> #inclu ...
- 非常可乐 HDU - 1495
大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为.因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多.但see ...
- mysql 时间戳转换 、cnd、dns 通俗理解
- 『MXNet』第十一弹_符号式编程初探
一.符号分类 符号对我们想要进行的计算进行了描述, 下图展示了符号如何对计算进行描述. 我们定义了符号变量A, 符号变量B, 生成了符号变量C, 其中, A, B为参数节点, C为内部节点! mxne ...