汉诺塔(Tower of Hanoi)是一个数学游戏:有三根柱子,其中一根柱子自底向上串着尺寸渐小的多个圆盘,遵循以下规则:
1、一次只能移动一个圆盘;
2、大圆盘不能放在小圆盘上面。
请问最少需要移动多少步,才能将所有圆盘移到另一根柱子上?
解答: 设移动 N N N个圆盘所需的最少步数为 F ( N ) F(N) F(N)。将三根柱子分别命名为A、B、C,要把 N N N个圆盘从A柱移至C柱,拆解为如下步骤:
1、将 N − 1 N-1 N−1个圆盘从A柱移至B柱,需要 F ( N − 1 ) F(N-1) F(N−1)步;
2、将余下的最大圆盘从A柱移至C柱,需要一步;
3、将 N − 1 N-1 N−1个圆盘从B柱移至C柱,需要 F ( N − 1 ) F(N-1) F(N−1)步。
得到最少移动步数的递推公式 F ( N ) = 2 F ( N − 1 ) + 1 F(N)=2F(N-1)+1 F(N)=2F(N−1)+1。易知 F ( 1 ) = 1 F(1)=1 F(1)=1,可得通项公式 F ( N ) = 2 N − 1 F(N)=2^N-1 F(N)=2N−1。
推广: 如果有四根或者更多柱子,所需的最少移动步数又是多少?
该算法采用递推的思想来求解多柱汉诺塔问题。设 M M M根柱子、 N N N个圆盘所需的最少移动步数为 F M ( N ) F_M(N) FM(N),将移动步骤拆解为:
1、将 r r r个圆盘移到另一根柱子上(非目标柱),需要 F M ( r ) F_M(r) FM(r)步;
2、将余下的 N − r N-r N−r个圆盘移至目标柱,需要 F M − 1 ( N − r ) F_{M-1}(N-r) FM−1(N−r)步;
3、将 r r r个圆盘移至目标柱,需要 F M ( r ) F_M(r) FM(r)步。
得到递推公式
F M ( N ) = min 1 ≤ r < N { 2 F M ( r ) + F M − 1 ( N − r ) } F_M(N)=\min\limits_{1\le r<N}\{2F_M(r)+F_{M-1}(N-r)\} FM(N)=1≤r<Nmin{2FM(r)+FM−1(N−r)}
代码:
#include
#include
#include
using namespace std;
// the least number of movements for n disks, m pegs
map<pair<int, int>, double> mapLeastMoves;
double LeastMoves(const int n, const int m) {
if (n < 0 || m < 3)
return -1;
if (n == 1)
return 1;
const auto index = make_pair(n, m);
if (mapLeastMoves.count(index) > 0)
return mapLeastMoves[index];
double least_moves;
if (m == 3) {
least_moves = pow(2., n) - 1;
} else {
least_moves = 2 * LeastMoves(n - 1, m) + LeastMoves(1, m - 1);
for (int r = n - 2; r > 0; --r) {
double moves = 2 * LeastMoves(r, m) + LeastMoves(n - r, m - 1);
if (moves < least_moves)
least_moves = moves;
else // a little optimization
break;
}
}
mapLeastMoves[index] = least_moves;
return least_moves;
}
void main() {
int M = 7, N = 10;
cout << "M\\N";
for (int n = 1; n <= N; ++n)
cout << "\tN = " << n;
cout << endl;
for (int m = 3; m <= M; ++m) {
cout << "M = " << m;
for (int n = 1; n <= N; ++n)
cout << "\t" << LeastMoves(n, m);
cout << endl;
}
system("pause");
}
输出:
M\N N = 1 N = 2 N = 3 N = 4 N = 5 N = 6 N = 7 N = 8 N = 9 N = 10
M = 3 1 3 7 15 31 63 127 255 511 1023
M = 4 1 3 5 9 13 17 25 33 41 49
M = 5 1 3 5 7 11 15 19 23 27 31
M = 6 1 3 5 7 9 13 17 21 25 29
M = 7 1 3 5 7 9 11 15 19 23 27
将 F M − 1 ( N − r ) F_{M-1}(N-r) FM−1(N−r)继续展开, F M ( N ) F_M(N) FM(N)的推导公式可以改写成如下形式
F M ( N ) = min r M , r M − 1 , … , r 3 { 2 [ F M ( r M ) + F M − 1 ( r M − 1 ) + ⋯ + F 3 ( r 3 ) ] + 1 } , s . t . { 0 ≤ r m < N , ∀ m ∈ [ 3 , M ] ∑ m = 3 M r m + 1 = N F_M(N)=\min\limits_{r_M,r_{M-1},\dots,r_3}\{2[F_M(r_M)+F_{M-1}(r_{M-1})+\dots+F_3(r_3)]+1\},\\ s.t.\quad \begin{cases} 0\le r_m<N,\forall m\in[3,M]\\ \sum_{m=3}^M{r_m}+1=N \end{cases} FM(N)=rM,rM−1,…,r3min{2[FM(rM)+FM−1(rM−1)+⋯+F3(r3)]+1},s.t.{0≤rm<N,∀m∈[3,M]∑m=3Mrm+1=N
用 Δ \Delta Δ表示 N N N加一时 F M ( N ) F_M(N) FM(N)的增量,设 Δ F M ( N ) = F M ( N ) − F M ( N − 1 ) \Delta F_M(N)=F_M(N)-F_M(N-1) ΔFM(N)=FM(N)−FM(N−1),易得
{ Δ F M ( 1 ) = 1 Δ F M ( N + 1 ) = 2 min m ∈ [ 3 , M ] { Δ F m ( r m + 1 ) } Δ F M ( N + 1 ) ≥ Δ F M ( N ) \begin{cases} \Delta F_M(1)=1\\ \Delta F_M(N+1)=2\min\limits_{m\in[3,M]}\{\Delta F_m(r_m+1)\}\\ \Delta F_M(N+1)\ge\Delta F_M(N) \end{cases} ⎩⎪⎪⎨⎪⎪⎧ΔFM(1)=1ΔFM(N+1)=2m∈[3,M]min{ΔFm(rm+1)}ΔFM(N+1)≥ΔFM(N)
若 r m + 1 = 1 , ∃ m ∈ [ 3 , M ] r_m+1=1,\exists m\in[3,M] rm+1=1,∃m∈[3,M],则 Δ F M ( N + 1 ) = 2 Δ F m ( 1 ) = 2 \Delta F_M(N+1)=2\Delta F_m(1)=2 ΔFM(N+1)=2ΔFm(1)=2。此时 ∑ m = 3 M r m < ∑ m = 3 M 1 = M − 2    ⟹    N < M − 1 \sum_{m=3}^M{r_m}<\sum_{m=3}^M{1}=M-2\implies N<M-1 ∑m=3Mrm<∑m=3M1=M−2⟹N<M−1,将 N + 1 N+1 N+1替换为 N N N,可知
Δ F M ( N ) = 2 , if 1 < N ≤ M − 1 \Delta F_M(N)=2, \text{ if }1<N\le M-1 ΔFM(N)=2, if 1<N≤M−1
若 r m + 1 > 1 , ∀ m ∈ [ 3 , M ] r_m+1>1,\forall m\in[3,M] rm+1>1,∀m∈[3,M],且 r m + 1 ≤ m − 1 , ∃ m ∈ [ 3 , M ] r_m+1\le m-1,\exists m\in[3,M] rm+1≤m−1,∃m∈[3,M],则 Δ F M ( N + 1 ) = 2 Δ F m ( r m + 1 ) = 4 \Delta F_M(N+1)=2\Delta F_m(r_m+1)=4 ΔFM(N+1)=2ΔFm(rm+1)=4。此时 ∑ m = 3 M r m < ∑ m = 3 M ( m − 1 ) = 1 2 M ( M − 1 ) − 1    ⟹    N < 1 2 M ( M − 1 ) \sum_{m=3}^M{r_m}<\sum_{m=3}^M(m-1)=\frac{1}{2}M(M-1)-1\implies N<\frac{1}{2}M(M-1) ∑m=3Mrm<∑m=3M(m−1)=21M(M−1)−1⟹N<21M(M−1),将 N + 1 N+1 N+1替换为 N N N,可知
Δ F M ( N ) = 4 , if M − 1 < N ≤ 1 2 M ( M − 1 ) \Delta F_M(N)=4, \text{ if }M-1<N\le\frac{1}{2}M(M-1) ΔFM(N)=4, if M−1<N≤21M(M−1)
若 r m + 1 > m − 1 , ∀ m ∈ [ 3 , M ] r_m+1>m-1,\forall m\in[3,M] rm+1>m−1,∀m∈[3,M],且 r m + 1 ≤ 1 2 M ( M − 1 ) , ∃ m ∈ [ 3 , M ] r_m+1\le \frac{1}{2}M(M-1),\exists m\in[3,M] rm+1≤21M(M−1),∃m∈[3,M],则 Δ F M ( N + 1 ) = 2 Δ F m ( r m + 1 ) = 8 \Delta F_M(N+1)=2\Delta F_m(r_m+1)=8 ΔFM(N+1)=2ΔFm(rm+1)=8。此时 ∑ m = 3 M r m < ∑ m = 3 M 1 2 m ( m − 1 ) = 1 6 ( M + 1 ) M ( M − 1 ) − 1    ⟹    N < 1 6 ( M + 1 ) M ( M − 1 ) \sum_{m=3}^M{r_m}<\sum_{m=3}^M\frac{1}{2}m(m-1)=\frac{1}{6}(M+1)M(M-1)-1\implies N<\frac{1}{6}(M+1)M(M-1) ∑m=3Mrm<∑m=3M21m(m−1)=61(M+1)M(M−1)−1⟹N<61(M+1)M(M−1),将 N + 1 N+1 N+1替换为 N N N,可知
Δ F M ( N ) = 8 , if 1 2 M ( M − 1 ) < N ≤ 1 6 ( M + 1 ) M ( M − 1 ) \Delta F_M(N)=8, \text{ if }\frac{1}{2}M(M-1)<N\le\frac{1}{6}(M+1)M(M-1) ΔFM(N)=8, if 21M(M−1)<N≤61(M+1)M(M−1)
从上式中找寻规律,由数学归纳法可以证得
Δ F M ( N ) = 2 t , if C M − 3 + t M − 2 < N ≤ C M − 2 + t M − 2 \Delta F_M(N)=2^t, \text{ if }C_{M-3+t}^{M-2}<N\le C_{M-2+t}^{M-2} ΔFM(N)=2t, if CM−3+tM−2<N≤CM−2+tM−2
由 F M ( N ) = ∑ n = 1 N Δ F M ( n ) F_M(N)=\sum_{n=1}^N{\Delta F_M(n)} FM(N)=∑n=1NΔFM(n)可知,对于 M = k + 2 M=k+2 M=k+2根柱子、 N N N个圆盘的汉诺塔问题,
F M ( N ) = 1 + ∑ t = 1 T − 1 2 t ( C k + t k − C k − 1 + t k ) + 2 T ( N − C k − 1 + T k ) , if C k − 1 + T k < N ≤ C k + T k F_M(N)=1+\sum_{t=1}^{T-1}{2^t(C_{k+t}^k-C_{k-1+t}^k)}+2^{T}(N-C_{k-1+T}^k), \text{ if }C_{k-1+T}^{k}<N\le C_{k+T}^{k} FM(N)=1+t=1∑T−12t(Ck+tk−Ck−1+tk)+2T(N−Ck−1+Tk), if Ck−1+Tk<N≤Ck+Tk