题意:给定N(1<= N <=64)个盘子和M(4<= M <= 65)根柱子,问把N个盘子从1号柱子移动到M号柱子所需要的最少步数,并且输出移动过程。

分析:设f[i][j]表示将i个盘通过j个柱子从第一根柱子移动到最后一根柱子所需要的最少次数,f[i][j]的得到的最优移动方案是先将最小的path[i][j]个盘移动到某一根柱子上,然后通过一个dfs输出移动次序。

#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <stack>
#include <algorithm>
using namespace std; typedef unsigned long long LL;
const int N = ;
LL f[][];
// f[i][j]表示将i个盘通过j个柱子从第一根柱子移动到最后一根柱子所需要的最少次数
int path[][]; // 表示f[i][j]的得到的最优移动方案是先将最小的path[i][j]个盘移动到某一根柱子上
int n, m;
stack<int>stk[];
char ocp[]; void pre() {
memset(f, 0x3f, sizeof (f));
for (int i = ; i <= ; ++i) {
f[][i] = ;
f[][i] = ;
}
for (int i = ; i <= ; ++i) { // 初始化三根柱子的情况
f[i][] = f[i-][] * + ;
path[i][] = i-;
}
for (int i = ; i <= ; ++i) {
for (int j = ; j <= ; ++j) {
for (int k = ; k < i; ++k) {
if (f[i][j] > f[i-k][j-] + *f[k][j]) {
f[i][j] = f[i-k][j-] + *f[k][j];
path[i][j] = k;
}
}
}
}
}
/*
move 2 from 1 to 2
move 1 from 3 to 2 atop 2
*/ void display(int an, int am, int sta, int end) {
if (an == ) {
if (stk[end].size()) {
printf("move %d from %d to %d atop %d\n", stk[sta].top(), sta, end, stk[end].top());
} else {
printf("move %d from %d to %d\n", stk[sta].top(), sta, end);
}
stk[end].push(stk[sta].top());
stk[sta].pop();
return;
}
int peg = ;
for (int i = ; i <= m; ++i) {
if (i != sta && i != end && !ocp[i]) {
peg = i;
break;
}
}
display(path[an][am], am, sta, peg);
ocp[peg] = ;
display(an-path[an][am], am-, sta, end);
ocp[peg] = ;
display(path[an][am], am, peg, end);
} void solve() {
for (int i = ; i <= m; ++i) while (!stk[i].empty()) stk[i].pop();
for (int i = n; i >= ; --i) stk[].push(i);
memset(ocp, , sizeof (ocp));
printf("%llu\n", f[n][m]);
display(n, m, , m);
} int main() {
pre();
int T;
scanf("%d", &T);
while (T--) {
scanf("%d %d", &n, &m);
solve();
}
return ;
}

ZOJ-2338 The Towers of Hanoi Revisited 输出汉诺塔的最优解移动过程的更多相关文章

  1. zoj 2338 The Towers of Hanoi Revisited

    The Towers of Hanoi Revisited Time Limit: 5 Seconds Memory Limit: 32768 KB Special Judge You all mus ...

  2. 1223: 输出汉诺塔问题的盘子移动步骤(Java)

    一.题目 http://acm.wust.edu.cn/problem.php?id=1223&soj=0 二.代码 import java.util.*; public class Main ...

  3. 汉诺塔-Hanoi

    1. 问题来源: 汉诺塔(河内塔)问题是印度的一个古老的传说. 法国数学家爱德华·卢卡斯曾编写过一个印度的古老传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针.印度教的主神梵 ...

  4. hanoi(汉诺塔)递归实现

    汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘.大梵天命令婆罗门把圆盘从下面开始按大小顺序 ...

  5. SGU 202 The Towers of Hanoi Revisited (DP+递归)

    转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove 题意 :n个圆盘,m个柱子的汉诺塔输出步骤. ht ...

  6. [CareerCup] 3.4 Towers of Hanoi 汉诺塔

    3.4 In the classic problem of the Towers of Hanoi, you have 3 towers and N disks of different sizes ...

  7. 《hanoi(汉诺塔)问题》求解

    //Hanoi(汉诺)塔问题.这是一个古典的数学问题,用递归方法求解.问题如下: /* 古代有一个梵塔,塔内有3个座A,B,C,开始时A座上有64个盘子,盘子大小不等,大的在下,小的在上. 有一个老和 ...

  8. 汉诺塔 Hanoi Tower

    电影<猩球崛起>刚开始的时候,年轻的Caesar在玩一种很有意思的游戏,就是汉诺塔...... 汉诺塔源自一个古老的印度传说:在世界的中心贝拿勒斯的圣庙里,一块黄铜板上插着三支宝石针.印度 ...

  9. [js - 算法可视化] 汉诺塔(Hanoi)演示程序

    前段时间偶然看到有个日本人很早之前写了js的多种排序程序,使用js+html实现的排序动画,效果非常好. 受此启发,我决定写几个js的算法动画,第一个就用汉诺塔. 演示地址:http://tut.ap ...

随机推荐

  1. java中使用反射往一个泛型是Integer类型的ArrayList中添加字符串,反射的案例1.

    //------------------------- //废话不多说,直接上代码.代码里面添加了详细的解释. import java.lang.reflect.Constructor; import ...

  2. Java中常见数据结构:list与map

    1:集合 Collection(单列集合) List(有序,可重复) ArrayList 底层数据结构是数组,查询快,增删慢 线程不安全,效率高 Vector 底层数据结构是数组,查询快,增删慢 线程 ...

  3. Xcode运行的错误bug收集

    libopencore-amrnb.a(wrapper.o)' does not contain bitcode. You must rebuild it with bitcode enabled ( ...

  4. mysqldump备份过程中都干了些什么

    mysqldump备份方便,易读,功能丰富,相信大家都有 使用过这个命令进行备份,但是这个命令在备份的过程中都做了写什么呢,下面打开general_log进行查看: 1.登录mysql命令行客户端: ...

  5. 20145227 《Java程序设计》第7周学习总结

    20145227 <Java程序设计>第7周学习总结 教材学习内容总结 第十二章 Lambda 如果使用JDK8的话,可以使用Lambda特性去除重复的信息. 在只有Lambda表达式的情 ...

  6. Android studio中设置颜色的状态选择器

    <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item andro ...

  7. DelegateCommand.cs

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.W ...

  8. 20151124001 关闭C#主窗体弹出是否关闭对话框

    关闭C#主窗体弹出是否关闭对话框 private void Frm_Main_FormClosing(object sender, FormClosingEventArgs e)        {   ...

  9. if else 语句练习

    一.if  else 语句.

  10. 【Java】hashcode()和equals()

    大家知道,在集合中判断集合中的两个元素是否相同,依赖的是hashcode()和equals()两个方法. > 一个简单的实验 public class Teacher { private Int ...