四柱加强版汉诺塔HanoiTower----是甜蜜还是烦恼
我想很多人第一次学习递归的时候,老师或者书本上可能会举汉诺塔的例子。
但是今天,我们讨论的重点不是简单的汉诺塔算法,而是三柱汉诺塔的延伸。先来看看经典的三柱汉诺塔。
一、三柱汉诺塔(Hanoi_Three):
我想大家对于三柱汉诺塔的理解以及算法的实现应该是很熟练了。
我在这里简单的过一遍三柱汉诺塔的算法思想:
有A、B、C三根柱子,A柱上有n个盘子,现在需要将A上所有的盘子转移到C上,请给出搬运次数最少的步骤。
算法思想:
1、将A上n-1个盘子以C为缓存,全部转移到 B 柱上。
2、将A上留下的第n个盘子,直接转移到 C 柱上。
3、将B上的n-1个盘子,以A为缓存,全部转移到 C 柱上。
很容易得到算法的递归方程为:T(n)=2*T(n-1)+1,不难算出步数是T(n)=2^n-1。
具体的代码如下:

二、四柱汉诺塔(Hanoi_Four):
当柱子为四根时,对于只是将盘子全部转移到另一根柱子上这个目的来说,是大大降低了难度,而且算法的复杂度也大大降低了。但是,这个时候,如果要你找到一个最优的、步骤最少的实现方法,可以说难度是提升了一个数量级。
有些人可能会质疑,为什么,我用三柱汉诺塔的思想不是很优化了吗?
别急,且让我慢慢向你道来。
先来看看这种‘看上去很合理’的解法:
假设,A,B,C,D,分别为:源位置,缓存,缓存,目的位置。
因为三柱的时候,我们是将A的前n-1个盘子放到B上缓存,然后将第n个盘子放到C柱上。
现在的情况好很多,有两个可以缓存的柱子,因此,看上去移动起来更加方便,原来B上需要缓存的n-1个盘子,现在可以只是n-2个盘子,而将第n-1个盘子放到C上缓存。
具体的流程如下(非最优解法):
1、从A借助C、D将 n-2个盘子移动到B上。
2、将第n-1个盘子移动到C上。
3、将第n个盘子移动到D上。
4、将第n-1个盘子移动到D上。
5、从B借助A、C将 n-2个盘子全部移动到D上。
看上去,非常完美,笔者也一度觉得这个思想没有破绽,甚至我还自以为找到了k根柱子汉诺塔的通用方法(想当然的将B柱上缓存的数量从n-2个,改为n-(k-2)个盘子)。直到我看了这篇文章:多柱汉诺塔最优算法设计探究。
虽然我们想到让盘子尽量不发生重叠来保证步数的最少,但是这并不能绝对保证。或许在盘子较少的情况下是可行的,但是盘子增多时,那些多余的只有一个盘子的柱子是可以加以利用的(可能的优化在这里)。虽然这么做加多了每次的移动步数,但是却从另一个侧面减少了递归的数量,因此我们需要从这里边找一个平衡点。
下面我们来看看,1941年,美国的J. S. Frame,给出的四柱汉诺塔的算法思想,也叫Frame算法:
1、用4柱汉诺塔算法把A柱上部分的n- r个碟子通过C柱和D柱移到B柱上【F( n- r )步】。
2、用3柱汉诺塔经典算法把A柱上剩余的r个碟子通过C柱移到D柱上【2^r-1步】(参照上述三柱时的情况)。
3、用4柱汉诺塔算法把B柱上的n-r个碟子通过A柱和C柱移到D柱上【F(n-r)步】。
4、依据上边规则求出所有r(1≤r≤n)情况下步数f(n),取最小值得最终解。
因此Frame算法的递归方程如下:
F(n)=min(2*F(n-r)+2^r-1),(1≤r≤n)。
大家有没有发现,其实,这个算法思想跟我们之前认为合理的算法基本一致,差别只是在于他将我们的n-2个碟子缓存到B上,改为了将n- r个碟子转移到B柱上。
差别即使核心,这个算法的核心,就是计算n个盘子的情况下,r为何值时,能够使得算法最优。
找到了核心,我们现在的任务就明确了,就是对r值的计算。
这里给出了一个较笨的方法--枚举(不知道各位有没有其他方法)。就是将一定范围内的n与r的所有取值带入,得到满足F(n)为最小值的r的值,记为K[n] = r;
具体的代码如下:
得到各个n对于的r之后,算法将变的非常简单,具体实现如下:

到这里,四柱汉诺塔的算法基本讲完了。
有兴趣的同学,可以继续归纳多柱汉诺塔的实现方法,欢迎交流指导!
很多时候,看似合理的背后,其实是一种思维定势。。。
from: http://blog.csdn.NET/cyh_24/article/details/8075578
四柱加强版汉诺塔HanoiTower----是甜蜜还是烦恼的更多相关文章
- hdu 1207 四柱汉诺塔
		
递推,汉诺塔I的变形. 这题真心没想到正确解法,越想越迷糊.这题看了别人题解过得,以后还是自己多想想,脚步太快并非好事. 贴上分析: 分析:设F[n]为所求的最小步数,显然,当n=1时,F[n]= ...
 - 汉诺塔的问题:4个柱子,如果塔的个数变位a,b,c,d四个,现要将n个圆盘从a全部移到d,移动规则不变
		
四柱汉诺塔问题的求解程序.解题思路:如a,b,c,d四柱. 要把a柱第n个盘移到目标柱子(d柱),先把上层 分两为两部份,上半部份移到b柱,下半部分移到c柱,再把第n盘移到 目标柱子,然后,c柱盘子再 ...
 - 4柱汉诺塔(zz)
		
多柱汉诺塔可以用Frame–Stewart算法来解决. The Frame–Stewart algorithm, giving a presumably optimal solution for fo ...
 - 多柱汉诺塔问题“通解”——c++
		
多柱汉诺塔问题 绪言 有位同学看到了我的初赛模拟卷上有一道关于汉诺塔的数学题.大概就是要求4柱20盘的最小移动次数. 他的数学很不错,找到了应该怎样推. 如果要把n个盘子移到另一个柱子上,步骤如下: ...
 - fzu1036四塔问题(汉诺塔问题拓展)
		
#include<iostream> #include<cstdio> #include<cmath> using namespace std; ]; int ru ...
 - UVA 10254 - The Priest Mathematician (dp | 汉诺塔 | 找规律 | 大数)
		
本文出自 http://blog.csdn.net/shuangde800 题目点击打开链接 题意: 汉诺塔游戏请看 百度百科 正常的汉诺塔游戏是只有3个柱子,并且如果有n个圆盘,至少需要2^n- ...
 - 化繁为简 经典的汉诺塔递归问题 in Java
		
问题描述 在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针.印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔.不论白天黑 ...
 - python中关于汉诺塔问题和使用turtle库实现其搬运过程
		
一.汉诺塔问题 汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘.大梵天命令婆罗门把圆盘从下面开始按 ...
 - python汉诺塔问题的递归理解
		
一.问题背景 汉诺塔问题是源于印度一个古老传说. 源于印度一个古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘.大梵天命令婆罗门把圆盘从下 ...
 
随机推荐
- 如何将portfolio产品图片上的悬停去掉?
			
在Avada主题里,文章和portfolio的分类界面的图片,鼠标移入后都会出现这个东西 那么如何把它去掉,改为直接点击产品图片后进入产品详情页呢? 在theme option里搜索image rol ...
 - IT技术有感
			
今天看技术文章,spring相关的,某一个点以前每次看一直不理解, 可是不知道为什么隔了1年左右,中间什么都没做,现在却都懂了. 在看懂的那一刻,笼罩在我心上的躁动突然平静了许多,我的心这一年来前所未 ...
 - Trensient的使用介绍
			
1. transient的作用及使用方法 我们都知道一个对象只要实现了Serilizable接口,这个对象就可以被序列化,java的这种序列化模式为开发者提供了很多便利,我们可以不必关系具体序列化的过 ...
 - python/MySQL(索引、执行计划、BDA、分页)
			
---恢复内容开始--- python/MySQL(索引.执行计划.BDA.分页) MySQL索引: 所谓索引的就是具有(约束和加速查找的一种方式) 创建索引的缺点是对数据进行(修改.更新.删除) ...
 - uestc 1703一道更简单的字符串题目
			
https://vjudge.net/problem/UESTC-1703 题意:略 思路: 枚举+字符串hash. ans从1到len开始枚举字符串的长度,然后就依次比较各段长度为ans的字符串的h ...
 - SpringBoot(六):springboot热部署
			
在j2ee项目开发中,热部署插件是JRebel.JRebel的使用为开发人员带来了极大的帮助,且挺高了开发便捷.而在SpringBoot开发生态环境中,SpringBoot热部署常用插件是:sprin ...
 - React-Native(三):React Native是基于React设计的
			
React Native是基于React js设计的. 参考:<React 入门实例教程> React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript ...
 - 使用java客户端调用redis
			
Redis支持很多编程语言的客户端,有C.C#.C++.Clojure.Common Lisp.Erlang.Go.Lua.Objective-C.PHP.Ruby.Scala,甚至更时髦的Node. ...
 - heightcharts点击曲线图获取返回值的问题(ios点击图表第一次无法触发点击事件解决方法)
			
需求:用的heightcharts插件,点击曲线图想获得所点击点的返回值,如图 问题代码: (function chart_line(){ var data={"title":[& ...
 - ConcurrentHashMap基于JDK1.8源码剖析
			
前言 声明,本文用的是jdk1.8 前面章节回顾: Collection总览 List集合就这么简单[源码剖析] Map集合.散列表.红黑树介绍 HashMap就是这么简单[源码剖析] LinkedH ...