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 ...
随机推荐
- The folder is already a source folder
不知为啥,创建了一个maven项目后,发现只有src/main/resources这个资源文件夹,然后,右键新建 Source Folder 时提示 “The folder is already a ...
- 力扣(LeetCode)476. 数字的补数
给定一个正整数,输出它的补数.补数是对该数的二进制表示取反. 注意: 给定的整数保证在32位带符号整数的范围内. 你可以假定二进制数不包含前导零位. 示例 1: 输入: 5 输出: 2 解释: 5的二 ...
- sort-插入排序
void sort_insertion(vector<int> &v) { for(int i=1;i<v.size();i++) { for(int j=i;j>0; ...
- Lua和C++交互 学习记录之二:栈操作
主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3 参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 1 ...
- 牛客小白月赛7 B 自杀游戏
自杀游戏 思路: sg函数 代码: #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include&l ...
- redhat 7.0 配置Bond
把/etc/sysconfig/network-scripts/目录下的ifcfg-bond*文件手动移动到/tmp目录. 重启网络:systemctl restart NetworkManager ...
- 输出图片格式BARTENDER
try { BarTender.Application btApp = new BarTender.Application(); BarTe ...
- highly variable gene | 高变异基因的选择 | feature selection | 特征选择
在做单细胞的时候,有很多基因属于noise,就是变化没有规律,或者无显著变化的基因.在后续分析之前,我们需要把它们去掉. 以下是一种找出highly variable gene的方法: The fea ...
- English trip V1 - B 5.Is It Cold Outside? 外面很冷? Teacher:Corrine Key: weather
In this lesson you will learn to talk about the weather. 本节课将学习到关于天气 课上内容(Lesson) 词汇(Key Word ) # 关于 ...
- 如何使用Web3.js API 在页面中进行转账
本文介绍如何使用Web3.js API 在页面中进行转账,是我翻译的文档Web3.js 0.2x 中文版 及 区块链全栈-以太坊DAPP开发实战 中Demo的文章说明. 写在前面 阅读本文前,你应该对 ...