背景
漢諾塔(又稱河內塔)問題是源於印度一個古老傳說的益智玩具。大梵天創造世界的時候做了三根金剛石柱子,在一根柱子上從下往上按照大小順序摞着64片黃金圓盤。大梵天命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。並且規定,在小圓盤上不能放大圓盤,在三根柱子之間一次只能移動一個圓盤。
漢諾塔游戲的目標是將A上的n個圓盤移至C上,一次只能移一片圓盤,且只允許小的圓盤在大的圓盤上。
思路
研究之后不難發現不管是幾層(設為n層)的漢諾塔其解法都分為三步:
1.將n-1層從A移到B
2.將A上最后一個移至C
3.將B上的n-1個移到C
代碼實現
count = 0
def move(n, a, b, c):
global count
if n == 1:
count += 1
print('第%d次:' % count + a + '------>' + c)
else:
move(n - 1, a, c, b)
move(1, a, b, c)
move(n - 1, b, a, c)
num = int(input("請輸入漢諾塔層數:"))
move(num, 'A', 'B', 'C')
print("漢諾塔層數:" + str(num))
print("共執行了%d次移動" % count)
規律
從執行結果中我們發現,解漢諾塔的最少操作次數隨着漢諾塔層數的增加構成了一個特殊數列,H⑴ = 1
H(n) = 2*H(n-1)+1 (n>1),python實現如下:
def count(n):
if n == 1:
return 1
else:
return 2 * count(n - 1) + 1
disc = {'%d層' % i: count(i) for i in range(1, 6)}#這里暫定為5層
print(disc)
輸出的字典對應了層數於操作次數的關系:
{'1層': 1, '2層': 3, '3層': 7, '4層': 15, '5層': 31}
小劇場:遞歸是個啥?
作者:Fireman A
鏈接:https://www.zhihu.com/question/24385418/answer/257751077
來源:知乎
對遞歸的理解的要點主要在於放棄!
放棄你對於理解和跟蹤遞歸全程的企圖,只理解遞歸兩層之間的交接,以及遞歸終結的條件。
想象你來到某個熱帶叢林,意外發現了十層之高的漢諾塔。正當你苦苦思索如何搬動它時,林中出來一個土著,毛遂自薦要幫你搬塔。他名叫二傻,戴着一個草帽,草帽上有一個2字,號稱會把一到二號盤搬到任意柱。
你靈機一動,問道:“你該不會有個兄弟叫三傻吧?”
“對對,老爺你咋知道的?他會搬一到三號盤。“
”那你去把他叫來,我不需要你了。“
於是三傻來了,他也帶着個草帽,上面有個3字。
你說:”三傻,你幫我把頭三個盤子移到c柱吧。“
三傻沉吟了一會,走進樹林,你聽見他大叫:”二傻,出來幫我把頭兩個盤子搬到C!“
由於天氣炎熱你開始打瞌睡。朦朧中你沒看見二傻是怎么工作的,二傻干完以后,走入林中大叫一聲:“老三,我干完了!”
三傻出來,把三號盤從A搬到B,然后又去叫二傻:“老二,幫我把頭兩個盤子搬回A!”
余下的我就不多說了,總之三傻其實只搬三號盤,其他叫二傻出來干。最后一步是三傻把三號盤搬到C,然后呼叫二傻來把頭兩個盤子搬回C
事情完了之后你把三傻叫來,對他說:“其實你不知道怎么具體一步一步把三個盤子搬到C,是吧?”
三傻不解地說:“我不是把任務干完了?”
你說:“可你其實叫你兄弟二傻干了大部分工作呀?”
三傻說:“我外包給他和你屁相干?”
你問到:“二傻是不是也外包給了誰?“
三傻笑了:“這跟我有屁相干?”
你苦苦思索了一夜,第二天,你走入林中大叫:“十傻,你在哪?”
一個頭上帶着10號草帽的人,十傻,應聲而出:“老爺,你有什么事?”
“我要你幫把1到10號盤子搬到C柱“
“好的,老爺。“十傻轉身就向林內走。
“慢着,你該不是回去叫你兄弟九傻吧“
“老爺你怎么知道的?“
“所以你使喚他把頭九個盤子搬過來搬過去,你只要搬幾次十號盤就好了,對嗎?“
“對呀!“
“你知不知道他是怎么干的?“
“這和我有屁相干?“
你嘆了一口氣,決定放棄。十傻開始干活。樹林里充滿了此起彼伏的叫聲:“九傻,來一下!“ “老八,到你了!““五傻!。。。“”三傻!。。。“”大傻!“
你注意到大傻從不叫人,但是大傻的工作也最簡單,他只是把一號盤搬來搬去。
若干年后,工作結束了。十傻來到你面前。你問十傻:“是誰教給你們這么干活的?“
十傻說:“我爸爸。他給我留了這張紙條。”
他從口袋里掏出一張小紙條,上面寫着:“照你帽子的號碼搬盤子到目標柱。如果有盤子壓住你,叫你上面一位哥哥把他搬走。如果有盤子占住你要去的柱子,叫你哥哥把它搬到不礙事的地方。等你的盤子搬到了目標,叫你哥哥把該壓在你上面的盤子搬回到你上頭。“
你不解地問:“那大傻沒有哥哥怎么辦?“
十傻笑了:“他只管一號盤,所以永遠不會碰到那兩個‘如果’,也沒有盤子該壓在一號上啊。”
但這時他忽然變了顏色,好像泄漏了巨大的機密。他驚慌地看了你一眼,飛快地逃入樹林。
第二天,你到樹林里去搜尋這十兄弟。他們已經不知去向。你找到了一個小屋,只容一個人居住,但是屋里有十頂草帽,寫着一到十號的號碼。