汉诺塔问题解法
- 格式:doc
- 大小:23.00 KB
- 文档页数:2
汉诺塔原理汉诺塔(Tower of Hanoi)是一个经典的数学问题,它源自印度的一个古老传说。
传说中,在贝拿勒斯(Benares)的圣庙里,一块黄铜板上插着三根宝石针。
初始时,所有的圆盘都放在一根针上,小的在上,大的在下。
这些圆盘按从小到大的次序排列。
有一个僧侣的职责是把这些圆盘从一个针移到另一个针上。
在移动过程中,可以借助第三根针,但有一个条件,就是在小的圆盘上不能放大的圆盘。
当所有的圆盘都从一根针上移到另一根针上时,这个世界就将毁灭。
汉诺塔问题的数学模型是,设有n个圆盘和三根柱子(我们称之为A、B、C),开始时所有的圆盘都叠在柱子A上,按照大小顺序从上到下叠放。
要求把所有的圆盘从柱子A移动到柱子C上,期间可以借助柱子B,但有一个限制条件,任何时刻都不能把一个大的圆盘放在一个小的圆盘上面。
汉诺塔问题的解法是一个典型的递归算法。
整个移动过程可以分解为三个步骤:1. 把n-1个圆盘从柱子A经过柱子C移动到柱子B上;2. 把第n个圆盘从柱子A移动到柱子C上;3. 把n-1个圆盘从柱子B经过柱子A移动到柱子C上。
这个过程可以用递归的方式来描述。
当我们解决n-1个圆盘的问题时,可以再次把它分解为n-2个圆盘的问题,直到最后只剩下一个圆盘的问题,这就是递归的思想。
递归算法虽然简洁,但是在实际应用中需要注意避免出现栈溢出的情况。
除了递归算法外,汉诺塔问题还有非递归的解法。
可以利用栈来模拟递归的过程,将每一步的移动操作保存在栈中,依次执行,直到所有的圆盘都移动到目标柱子上。
汉诺塔问题不仅是一个数学问题,更是一个思维训练的好题目。
它可以锻炼人的逻辑思维能力和动手能力。
在计算机科学中,递归算法是一种非常重要的思想,很多经典的算法问题都可以用递归的方式来解决。
总之,汉诺塔问题是一个古老而经典的数学问题,它不仅有着深奥的数学原理,更能锻炼人的思维能力。
通过研究汉诺塔问题,我们可以更好地理解递归算法的原理,提高自己的编程能力和解决问题的能力。
证明并推导汉诺塔(河内之塔)问题公式本⽂链接: 第⼀次遇到汉诺塔问题时我瞬间就被搞蒙了之后果断扔下不管了,今天再次遇到这个问题被搞蒙again ,在⽹上搜了好久愣是没让我找到证明汉诺塔问题可解和推导公式过程的资料,于是花了⼏个⼩时(谁让咱不太聪明呢,嘿嘿),最后终于想通了,记录下来希望对像我⼀样不聪明的⼈有所帮助。
证明可解汉诺塔问题:我⽤的是数学归纳法,假设圆盘的个数为n ,圆盘编号从上到下依次为1,2,3,4,……n ,证明如下①当 n = 1 时,从 A 移动到 C 显然能够完成,设需要移动的次数是a 。
②当 n = 2 时,由①可知从把 1 号盘⼦从 A 移动到 B 能够完成(B 和 C 是等效的)此时移动次数为a 。
之后把2号盘⼦移动到C 上⾯此时移动次数为a + 1。
这时把1号盘⼦从B 移动到C 和①是等价的,移动后总的移动次数是a = a + 1 + a 。
③当n = 3时,由②可知移动成下图的效果是可以实现的,此时移动的次数是a2,接着把3号盘⼦移动到C 上⾯此时移动的次数是a + 1,这时把1和2号盘⼦移动到C 上⾯(移动过程中3号盘⼦始终不会动)和②等效的,移动完成之后如下移动的总次数是a = a + 1 + a ④当n=4时,由③可知移动成下图的效果是可以实现的,此时移动的次数是a 把4号盘⼦从A 移动到C此时移动的次数是a + 1接下来把123号盘⼦从B 移动到C 的过程⼜和③等效了移动之后如下移动的总次数是a = a + 1 + a 假设当n= k 时,从A 移动到C 是可以实现的,那么当n=k+1时,可以移动到A 上⾯只剩k+1号盘⼦,B 上⾯依次是1,2,3,.....,k 号盘字,此时移动次数是a把k+1号盘⼦移动到C 上⾯,这时移动次数是a + 1接下来和n=k 时移动过程等效,移动完成后移动总次数是a = a + 1+ a可以得知移动k+1个盘⼦需要的次数与移动k 个盘⼦的次数之间的关系是:a = a + 1+ a = 2a + 1111 2 1 12 3 2 233 4 3 3k k k+1k kk+1 k k k所以a + 1 = 2*(a + 1)【这是个等⽐数列⾼中学过的】即a + 1 = (a1 +1)* 2 = 2 因此a = 2 - 1⾄此,证明完毕。
简述戴维南定理的解题过程戴维南定理,又被称为汉诺塔定理,是由数学家戴维南发现的一个有趣的定理,它的正式名称为“戴维南的运动定理”。
它算是一个组合数学定理,主要描述的是在找到最优解的过程中,可以用一种思维方法来分解各种技巧流程,从而达到相同的目标。
戴维南定理的定义是,在一个有目标的搜索问题中,当可以分割出若干子问题时,若每个子问题的最优解都是对本问题的最优解,则本问题的最优解就是求出每个子问题的最优解之和。
从定义来看,戴维南定理属于分解思维的理论,我们可以将最初的复杂问题分解为相互独立的子问题,然后按照子问题解决各自的最优解,最终综合各个子问题的最优解得出原问题的最优解。
应用戴维南定理解题的一般步骤如下:首先明确问题和约束条件,其次将复杂的问题分解为若干较小的子问题,每个子问题可以分别及独立地被解决,然后针对每个子问题按顺序设计有效的算法,最后从各个子问题中选择出最优解,综合得出最终的最优解。
具体解题步骤可以分为以下五个步骤:1、分析问题:首先要正确理解问题,了解问题的大致内容,以及解决问题所涉及的内容,例如,在汉诺塔定理的解题中,要分析汉诺塔的层数,以及每一层中的棋子数等;2、确定问题规模:根据问题所涉及到的内容,确定问题的规模,这个规模决定了解题的策略,例如,在汉诺塔定理的解题中,可以确定汉诺塔的层数,就知道有多少种可能性;3、用戴维南定理分解问题:根据问题分析出来的内容,将问题进行分解,用戴维南定理将汉诺塔定理分解为若干子问题,每个子问题可以独立解决;4、利用算法解决子问题:针对每个子问题,使用合适的算法来求解,可以利用递归算法求解汉诺塔定理的问题,这是一种比较容易求得的解法;5、综合结果:将各个子问题的最优解综合起来,就可以得到本问题的最优解。
显然,戴维南定理的解题步骤完全符合其定义的思想,即将复杂的问题分解为若干子问题,每个子问题可以分别及独立地被解决,最终将各个子问题的最优解综合起来,就可以得到本问题的最优解。
汉诺塔最少步数公式汉诺塔是一种经典的数学游戏,它的目标是将三个柱子上按照大小顺序排列的盘子,从起始柱子移动到目标柱子上。
为了达成这个目标,我们可以使用递归的方式来解决。
最少步数公式当我们需要将 n 个盘子从柱子 A 移动到柱子 C 时,最少需要多少步呢?经过数学推导可知,我们可以使用一个简单的公式来计算出最少步数:F(n) = 2F(n-1) + 1其中,n 表示盘子的数量,F(n) 表示将 n 个盘子从柱子 A 移动到柱子C 所需的最少步数。
公式意义为:将 n 个盘子从柱子 A 移动到柱子 C所需的最少步数等于先将 n-1 个盘子从柱子 A 移动到柱子 B,再将剩余的 1 个盘子从柱子 A 移动到柱子 C,最后将 n-1 个盘子从柱子 B 移动到柱子 C 所需的步数再加上 1。
举个例子,当盘子数量为 3 时,根据公式可知:F(3) = 2F(2) + 1 = 2(2F(1) + 1) + 1 = 2(2*1+1) + 1 = 7即将 3 个盘子从柱子 A 移动到柱子 C 最少需要 7 步。
递归算法通过递归算法,我们可以将盘子的移动过程拆分成多个小的子问题,每次处理一个子问题,直到最终解决所有问题。
具体的过程如下:1. 将前 n-1 个盘子从柱子 A 移动到柱子 B2. 将第 n 个盘子从柱子 A 移动到柱子 C3. 将前 n-1 个盘子从柱子 B 移动到柱子 C在每一次递归中,我们需要将当前问题拆分成三个子问题,并逐步解决这些子问题。
当盘子数量越来越少时,递归的规模也逐渐缩小,最终问题得到解决。
时间复杂度汉诺塔问题的时间复杂度为 O(2^n),其中 n 表示盘子数量。
这是由于在每一次递归中,我们需要处理两个子问题,因此总共需要递归 2^n-1 次。
虽然时间复杂度比较高,但在实际运用中,汉诺塔算法的问题规模往往比较小,因此并不会产生太大的性能问题。
总结汉诺塔问题是一种经典的递归算法,它的解法可以简单地用一个公式表示,并通过分治的方式实现。
汉诺塔百科名片汉诺塔初始状态汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。
上帝创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上安大小顺序摞着64片黄金圆盘。
上帝命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。
并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
目录由来汉诺塔与宇宙寿命concreteHAM:汉诺塔问题的程序实现由来汉诺塔与宇宙寿命concreteHAM:汉诺塔问题的程序实现展开编辑本段由来来源汉诺塔是源自印度神话里的玩具。
上帝创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按大小顺序摞着64片黄金圆盘。
上帝命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。
并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
传说在印度,有这么一个古老的传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。
印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。
不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。
僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。
不管这个传说的可信度有多大,如果考虑一下把64片金片,由一根针上移到另一根针上,并且始终保持上小下大的顺序。
这需要多少次移动呢?这里需要递归的方法。
假设有n片,移动次数是f(n).显然f(1)=1,f(2)=3,f(3)=7,且f(k+1)=2*f(k)+1。
此后不难证明f(n)=2^n-1。
n=64时,f(64)= 2^64-1=18446744073709551615假如每秒钟一次,共需多长时间呢?一个平年365天有31536000 秒,闰年366天有31622400秒,平均每年31556952秒,计算一下,18446744073709551615/31556952=584554049253.855年这表明移完这些金片需要5845亿年以上,而地球存在至今不过45亿年,太阳系的预期寿命据说也就是数百亿年。
汉诺塔河内塔是根据一个传说形成的一个问题:有三根杆子A,B,C。
A杆上有N个(N>1)穿孔圆盘,盘的尺寸由下到上依次变小。
要求按下列规则将所有圆盘移至C杆:提示:可将圆盘临时置于B杆,也可将从A杆移出的圆盘重新移回A杆,但都必须尊循上述两条规则。
问:如何移?最少要移动多少次?基本介绍有三根杆子A,B,C。
A杆上有N个(N>1)穿孔圆盘,盘的尺寸由下到上依次变小。
要求按下列规则将所有圆盘移至C杆:每次只能移动一个圆盘;大盘不能叠在小盘上面。
提示:可将圆盘临时置于B杆,也可将从A杆移出的圆盘重新移回A杆,但都必须尊循上述两条规则。
问:如何移?最少要移动多少次?汉诺塔是根据一个传说形成的一个问题:有三根杆子A,B,C。
A杆上有N个(N>1)穿孔圆盘,盘的尺寸由下到上依次变小。
要求按下列规则将所有圆盘移至C杆:每次只能移动一个圆盘;大盘不能叠在小盘上面。
提示:可将圆盘临时置于B杆,也可将从A杆移出的圆盘重新移回A杆,但都必须尊循上述两条规则。
问:如何移?最少要移动多少次?历史传说一位法国数学家曾编写过一个印度的古老传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。
印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。
不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。
僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。
不管这个传说的可信度有多大,如果考虑一下把64片金片,由一根针上移到另一根针上,并且始终保持上小下大的顺序。
这需要多少次移动呢?这里需要递归的方法。
假设有n片,移动次数是f(n).显然f⑴=1,f⑵=3,f⑶=7,且f(k+1)=2*f(k)+1。
此后不难证明f(n)=2^n-1。
汉诺塔(又称河内塔)问题其实是印度的一个古老的传说。
开天辟地的神勃拉玛(和中国的盘古差不多的神吧)在一个庙里留下了三根金刚石的棒,第一根上面套着64个圆的金片,最大的一个在底下,其余一个比一个小,依次叠上去,庙里的众僧不倦地把它们一个个地从这根棒搬到另一根棒上,规定可利用中间的一根棒作为帮助,但每次只能搬一个,而且大的不能放在小的上面。
计算结果非常恐怖(移动圆片的次数)18446744073709551615,众僧们即便是耗尽毕生精力也不可能完成金片的移动了。
算法介绍:其实算法非常简单,当盘子的个数为n时,移动的次数应等于2^n – 1(有兴趣的可以自己证明试试看)。
后来一位美国学者发现一种出人意料的简单方法,只要轮流进行两步操作就可以了。
首先把三根柱子按顺序排成品字型,把所有的圆盘按从大到小的顺序放在柱子A上,根据圆盘的数量确定柱子的排放顺序:若n为偶数,按顺时针方向依次摆放 A B C;若n为奇数,按顺时针方向依次摆放 A C B。
(1)按顺时针方向把圆盘1从现在的柱子移动到下一根柱子,即当n为偶数时,若圆盘1在柱子A,则把它移动到B;若圆盘1在柱子B,则把它移动到C;若圆盘1在柱子C,则把它移动到A。
(2)接着,把另外两根柱子上可以移动的圆盘移动到新的柱子上。
即把非空柱子上的圆盘移动到空柱子上,当两根柱子都非空时,移动较小的圆盘。
这一步没有明确规定移动哪个圆盘,你可能以为会有多种可能性,其实不然,可实施的行动是唯一的。
(3)反复进行(1)(2)操作,最后就能按规定完成汉诺塔的移动。
所以结果非常简单,就是按照移动规则向一个方向移动金片:如3阶汉诺塔的移动:A→C,A→B,C→B,A→C,B→A,B→C,A→C汉诺塔问题也是程序设计中的经典递归问题,下面我们将给出递归和非递归的不同实现源代码。
●汉诺塔算法的递归实现C++源代码#include <fstream>#include <iostream>using namespace std;ofstream fout("out.txt");void Move(int n,char x,char y){fout<<"把"<<n<<"号从"<<x<<"挪动到"<<y<<endl;}void Hannoi(int n,char a,char b,char c){if(n==1)Move(1,a,c);else{Hannoi(n-1,a,c,b);Move(n,a,c);Hannoi(n-1,b,a,c);}}int main(){fout<<"以下是7层汉诺塔的解法:"<<endl;Hannoi(7,'a','b','c');fout.close();cout<<"输出完毕!"<<endl;return 0;}●汉诺塔算法的递归实现C源代码:#include<stdio.h>void hanoi(int n,char A,char B,char C){if(n==1){printf("Move disk %d from %c to %c\n",n,A,C); }else{hanoi(n-1,A,C,B);printf("Move disk %d from %c to %c\n",n,A,C); hanoi(n-1,B,A,C);}}main(){int n;printf("请输入数字n以解决n阶汉诺塔问题:\n");scanf("%d",&n);hanoi(n,'A','B','C');}●汉诺塔算法的非递归实现C++源代码#include <iostream>using namespace std;//圆盘的个数最多为64const int MAX = 64;//用来表示每根柱子的信息struct st{int s[MAX]; //柱子上的圆盘存储情况int top; //栈顶,用来最上面的圆盘char name; //柱子的名字,可以是A,B,C中的一个int Top()//取栈顶元素{return s[top];}int Pop()//出栈{return s[top--];}void Push(int x)//入栈{s[++top] = x;}} ;long Pow(int x, int y); //计算x^yvoid Creat(st ta[], int n); //给结构数组设置初值void Hannuota(st ta[], long max); //移动汉诺塔的主要函数int main(void){int n;cin >> n; //输入圆盘的个数st ta[3]; //三根柱子的信息用结构数组存储Creat(ta, n); //给结构数组设置初值long max = Pow(2, n) - 1;//动的次数应等于2^n - 1 Hannuota(ta, max);//移动汉诺塔的主要函数system("pause");return 0;}void Creat(st ta[], int n){ta[0].name = 'A';ta[0].top = n-1;//把所有的圆盘按从大到小的顺序放在柱子A上for (int i=0; i<n; i++)ta[0].s[i] = n - i;//柱子B,C上开始没有没有圆盘ta[1].top = ta[2].top = 0;for (int i=0; i<n; i++)ta[1].s[i] = ta[2].s[i] = 0;//若n为偶数,按顺时针方向依次摆放 A B Cif (n%2 == 0){ta[1].name = 'B';ta[2].name = 'C';}else//若n为奇数,按顺时针方向依次摆放 A C B{ta[1].name = 'C';ta[2].name = 'B';}}long Pow(int x, int y){long sum = 1;for (int i=0; i<y; i++)sum *= x;return sum;}void Hannuota(st ta[], long max){int k = 0; //累计移动的次数int i = 0;int ch;while (k < max){//按顺时针方向把圆盘1从现在的柱子移动到下一根柱子ch = ta[i%3].Pop();ta[(i+1)%3].Push(ch);cout << ++k << ": " <<"Move disk " << ch << " from " << ta[i%3].name <<" to " << ta[(i+1)%3].name << endl;i++;//把另外两根柱子上可以移动的圆盘移动到新的柱子上if (k < max){//把非空柱子上的圆盘移动到空柱子上,当两根柱子都为空时,移动较小的圆盘if (ta[(i+1)%3].Top() == 0 ||ta[(i-1)%3].Top() > 0 &&ta[(i+1)%3].Top() > ta[(i-1)%3].Top()){ch = ta[(i-1)%3].Pop();ta[(i+1)%3].Push(ch);cout << ++k << ": " << "Move disk "<< ch << " from " << ta[(i-1)%3].name<< " to " << ta[(i+1)%3].name << endl;}else{ch = ta[(i+1)%3].Pop();ta[(i-1)%3].Push(ch);cout << ++k << ": " << "Move disk "<< ch << " from " << ta[(i+1)%3].name<< " to " << ta[(i-1)%3].name << endl;}}}}。
汉诺塔问题递归算法
?
汉诺塔问题是一个著名的递归问题,它有古老而神秘的历史。
据传汉诺塔问题是印度神梵天所创,它用来教导学生思考和探究问题的解决方案。
汉诺塔问题涉及三个不同的塔。
塔A、B、C,A塔上有N 块圆盘,从大到小排列,要把它们移动到另一个塔C上,此时有两个限制条件:(1)要求圆盘不能任意移动,必须从大到小排列,(2)只能一次移动一块盘子。
下面我们来看一下汉诺塔问题的递归解法,假设有N个圆盘,将它们移动到达C塔上。
首先将N-1个盘子移动到塔B,可以通过把盘子从A塔移动到B塔,再把A塔上余下的最后一个盘子移动到C塔,最后把B塔上的N-1个盘子移动到C塔。
同理,每次只移动一个盘子,可以把N-1个盘子从A移动到B,N-2个盘子从B移动到C,N-3个盘子从C移动到A,依次类推,直到只剩下一个盘子为止。
这样一来,每一次移动的结果就会递归到下一次移动,直到要移动的盘子数只有1左右时,再把它由一个塔移动到另一个塔,最终达到目的,完成汉诺塔的搬运。
通过汉诺塔问题的求解,我们可以更好地理解递归算法的概念,学习如何将一个复杂的问题分解成小的子问题进行求解,以达到目标。
汉诺塔问题也是众多著名算法的源泉,它为计算机科学发展做出了贡献。
汉诺塔原理范文汉诺塔(Hanoi Tower)是一种经典的数学问题,也是一种著名的智力游戏。
它的目标是将一个由大小不等的圆盘组成的塔从一根柱子移动到另一根柱子上,只能借助第三根柱子,且在移动过程中要遵循一些规则。
汉诺塔问题的解法非常简单,但其中蕴含的数学原理却非常有趣。
首先,让我们来了解一下汉诺塔问题的规则。
假设有三根柱子,分别标记为A、B和C。
有n个圆盘,从小到大依次堆叠在柱子A上。
目标是将这n个圆盘从柱子A上移动到柱子C上,中间可以借助柱子B进行临时存放,但是在移动过程中必须遵守以下规则:1.每次只能移动一个圆盘。
2.每次移动必须将圆盘从柱子的顶端移除,并且只能放置在另一根柱子的顶端。
3.任意一个圆盘不能放置在比它小的圆盘上。
接下来,让我们来探讨一下汉诺塔问题的解法。
对于简单的情况,当n=1时,只需将圆盘直接从柱子A移动到柱子C 即可。
这是一个基本的移动操作。
当n=2时,我们需要先将较小的圆盘从柱子A移动到柱子B,然后再将较大的圆盘从柱子A移动到柱子C,最后将较小的圆盘从柱子B移动到柱子C。
这样,我们就完成了这个问题的解。
对于n>2的情况,我们可以将这个问题分解为更小规模的子问题。
例如,当n=3时,我们可以先将最上面的两个圆盘从柱子A移动到柱子B,再将最大的圆盘从柱子A移动到柱子C,最后将两个圆盘从柱子B移动到柱子C。
这个操作序列与n=2时是相同的,因此我们可以利用相同的方法解决这个问题。
一般来说,可以利用递归的思想解决汉诺塔问题。
假设我们已经知道如何将n-1个圆盘从柱子A移动到柱子B上,那么将第n个圆盘从柱子A移动到柱子C的步骤如下:1.将n-1个圆盘从柱子A移动到柱子B(递归过程)。
2.将第n个圆盘从柱子A移动到柱子C。
3.将n-1个圆盘从柱子B移动到柱子C(递归过程)。
通过不断地进行递归操作,我们最终可以将所有的圆盘从柱子A移动到柱子C上,完成了汉诺塔问题的解。
需要注意的是,在每一次递归的过程中,我们都要将问题规模缩小为n-1,直到最基本的情况n=1汉诺塔问题的解法简单而直观,但其背后蕴含了递归思想的巧妙运用。
多柱汉诺塔最优算法转⾃1. 三柱汉诺塔三柱汉诺塔是经典的汉诺塔问题,在算法设计中是递归算法的典型问题。
其算法是这样的: ⾸先把A 柱上⾯的n- 1 个碟⼦通过C 柱移到B 柱上【T(n-1)步】,然后把A 柱剩下的⼀个碟⼦移到C 柱上【1步】, 最后把B 柱上所有的碟⼦通过A 柱移到C 柱上【T(n-1)步】。
很容易得到算法的递归⽅程为:T(n)=2*T(n-1)+1,因此,不难算出步数是T(n)=2^n-1。
对于三柱汉诺塔的算法的正确性⾃然是毫⽆争议的,我们需要的是从三柱汉诺塔的设计中引申出多柱汉诺塔的设计⽅法。
2. 四柱汉诺塔四柱汉诺塔并不是仅仅是多了⼀根柱⼦那么简单,所以我们先尝试从正常的思维出发来探究如何使移动步数最少。
⾸先我们会想到,三柱汉诺塔需要借助另⼀个柱⼦存放前n-1个盘⼦,再把第n个盘⼦移动到⽬的位置。
顺其⾃然的,四柱汉诺塔由于多了⼀个柱⼦,所以移动起来就更⽅便了,我们可以多留下⼀个盘⼦n-2,⽽不让它借位到其他柱⼦直接移动到⽬的位置。
这样我们就得出算法的基本流程:(1)从A借助C、D将 n-2个盘⼦移动到B上。
(2)将n-2移动到C上。
(3)将n-1移动到D上。
(4)将n-2移动到D上。
(5)从B借助A、C将 n-2个盘⼦移动到D上。
另外,这么设计是符合正常思维原则的。
以为随着柱⼦的个数增多,我们希望每次移动的时候盘⼦尽可能不发⽣折叠,也就是说我们希望除了需要借助存放n-2个盘⼦的柱⼦。
那么剩下的两个柱⼦可以允许⾄多两个盘⼦不发⽣折叠就能直接移动到⽬的位置,这样才使得移动起来⽐较⽅便,步骤也会⽐较少。
事实真的是如此吗?我们具体分析⼀下算法。
按照以上设计的算法流程,我们得到递归⽅程:F(n)=2*F(n-2)+3。
因此得到移动步数为:F(n)=4*2^(n/2)-3:n为奇数;F(n)=6*2^(n/2-1)-3:n为偶数。
下边列出6个盘⼦的移动步数:n 1 2 3 4 5 6F(n) 1 3 5 9 13 21到这⾥,我们已经看出我们的设计的算法已经和经典的汉诺塔算法⼏乎如出⼀辙了,甚⾄是如此的对称和谐!基于此我们甚⾄可以推⼴到M(M≥3)个柱⼦的情况,来得到我们希望的最优解,假设柱⼦编号为1,2,3…M算法主题框架流程应该如下:(1)从1柱借助3…M柱⼦将n-(M-2)个盘⼦移动到2柱上。