题目

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的更多相关文章

  1. UVa 10795 - A Different Task

    题目大意:给出n,表示说有n个大小不同的盘子,然后再给出每个盘子的初始位置和目标位置,要求计算出最少的步数使得每个盘子都移动到它的目标位置. 分析:  首先找最大不在目标柱子上的盘子K,因为如果最大的 ...

  2. UVA 10795 A Different Task(汉诺塔 递归))

    A Different Task The (Three peg) Tower of Hanoi problem is a popular one in computer science. Briefl ...

  3. UVA 10795 - A Different Task(递归)

     A Different Task  The (Three peg) Tower of Hanoi problem is a popular one in computer science. Brie ...

  4. 【汉诺塔问题】UVa 10795 - A Different Task

    [经典汉诺塔问题] 汉诺(Hanoi)塔问题:古代有一个梵塔,塔内有三个座A.B.C,A座上有64个盘子,盘子大小不等,大的在下,小的在上.有一个和尚想把这64个盘子从A座移到B座,但每次只能允许移动 ...

  5. UVA 10795 A Different Task(模拟)

    题目链接:https://vjudge.net/problem/UVA-10795 一道比较有思维含量的一道题: 注意一种分治的思想和“除了柱子x和柱子y之外的那个柱子”编号的问题. 首先在初始局面和 ...

  6. 数位dp总结 之 从入门到模板

    转发自WUST_WenHao巨巨的博客 基础篇 数位dp是一种计数用的dp,一般就是要统计一个区间[le,ri]内满足一些条件数的个数.所谓数位dp,字面意思就是在数位上进行dp咯.数位还算是比较好听 ...

  7. 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是 ...

  8. CF431D Random Task 二分+数位dp

    One day, after a difficult lecture a diligent student Sasha saw a graffitied desk in the classroom. ...

  9. uva 10817(数位dp)

    uva 10817(数位dp) 某校有m个教师和n个求职者,需讲授s个课程(1<=s<=8, 1<=m<=20, 1<=n<=100).已知每人的工资c(10000 ...

随机推荐

  1. django生成迁移文件

    1.创建虚拟环境 在终端上输入创建python3的虚拟环境 mkvirtualenv -p python3 虚拟环境的名字 安装django和pymysql 2.创建项目创建工程的命令: django ...

  2. Cocos Creator 脚本模板

    1.由于新建Cocos Creator脚本带有很多注释,并且有时候需要增加定制的默认注释,所以需要修改脚本生成模板. 2.在CocosCreator\resources\static\template ...

  3. 第 4 章 容器 - 029 - 限制容器的 Block IO

    限制容器的 Block IO Block IO 是另一种可以限制容器使用的资源. Block IO 指的是磁盘的读写,docker 可通过设置权重.限制 bps 和 iops 的方式控制容器读写磁盘的 ...

  4. Spring Boot入门第三天:配置日志系统和Druid数据库连接池。

    原文链接 一.日志管理 1.在application.properties文件中加入如下内容: logging.level.root=WARN logging.level.org.springfram ...

  5. R基本图形示例及代码(持续收集)

    分布图 hist(MetaData$genes, breaks = 100, main = "Gene number distribution", xlab = "Gen ...

  6. 掌握R语言中的apply函数族(转)

    转自:http://blog.fens.me/r-apply/ 前言 刚开始接触R语言时,会听到各种的R语言使用技巧,其中最重要的一条就是不要用循环,效率特别低,要用向量计算代替循环计算. 那么,这是 ...

  7. 分享基于EF+WCF的通用三层架构及解析

    本项目结合EF 4.3及WCF实现了经典三层架构,各层面向接口,WCF实现SOA,Repository封装调用,在此基础上实现了WCFContext,动态服务调用及一个分页的实例. 1. 项目架构图: ...

  8. Agile敏捷开发Planning Poker简介

    ​​关注嘉为科技,获取运维新知 一.为什么不用“人天”? 传统的IT项目,尤其是软件开发项目,往往使用“人天”来作为工作量评估的量词.甚至是代表一种评估方式.在软件项目开发经典著作<人月神话&g ...

  9. java中的Sort函数,你值得看

    基于C语言中的sort如此这么方便,自然而然,java中也有类似C的sort函数. 1.普通数组:Arrays.sort(数组名,开始位置,结束位置). 2.类中属性排序: 模板: class A { ...

  10. 字符串hash

    hash[i]=(hash[i-1]*p+idx(s[i]))%mod p和mod取不同的较大的素数