汉诺塔次数问题
汉诺塔是根据一个传说提出的问题:
有三根柱子A,B,C。A柱上有N个圆盘,并且N个圆盘从下到上,尺寸越来越小。要求在遵循以下规则的情况下将N个圆盘从A柱移动至C柱。
规则一:每次只能移动一个圆盘。
规则二:大圆盘绝对不能放在小圆盘之上。
规则三:可利用B柱,但不能违背规则一,规则二。
问:如何移动?至少移动多少次?
解法
第一步: 将较小的n-1个圆盘通过C柱,从A柱移动到B柱。
第二步: 将剩下的最大的一个圆盘移动到C柱。
第三步: 将n-1个圆盘通过A柱,移动到C柱上。
对于第三步而言,如果看作(n-2)个小圆盘和一个大圆盘,那解题思路便与第一第二布完全相似。于是,汉诺塔问题成为了递归算法的标准实例。
package com.demo;
import java.util.Scanner;
//汉诺塔
public class Main {
int n;
public Main(){
Scanner sys=new Scanner(System.in);
if(sys.hasNext()){
n=sys.nextInt();
}
sys.close();
System.out.println(getResult(n));
}
public int getResult(int n){
//n属于(0,20);
int sum=0; //移动次数
if(0==n){
return 0;
}if(1==n){
return 1;
}else{
sum=getResult(n-1)+sum; //将较小的n-1从A移到B
sum++; //将最大的一个从A移到C
sum=getResult(n-1)+sum;//将n-1个圆盘从B移到C
return sum;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new Main();
}
}
n | 步数 | 规律 |
---|---|---|
2 | 3 | 2 2 − 1 2^2-1 22−1 |
3 | 7 | 2 3 − 1 2^3-1 23−1 |
4 | 15 | 2 4 − 1 2^4-1 24−1 |
5 | 31 | 2 5 − 1 2^5-1 25−1 |
… | … | … |
写到这里,我们已经能够看出汉诺塔的次数正是( 2 n 2^n 2n-1)。
现在,再来分析我们的解题思路
第一步:sum=F(n-1);
第二步:sum=1;
第三步:sum=F(n-1);
所以sum=2F(n-1)+1;
于是 2 n 2^n 2n-1= 2F(n-1)+1;
而在数学上,F(n)=2F(n-1)+1,可以推导出F(n)=
2
n
−
1
2^n-1
2n−1,啧啧,如此巧合却又顺理成章,不得不让人赞叹前人的智慧啊。
这样一来,对于2的n次方,也多了一种递归求解法。实在是妙。