四柱漢諾塔,在a柱上有n個盤子,最少經過多少次移動能把盤子全部移動到d上?
將盤子人為分成上下兩個部分,上面部分是n-k個盤子,下面部分是k個盤子。那麼想要把總計n個盤子從a柱挪到d柱就相當於:
通過cd柱把上面n-k個盤子挪到b柱
+通過c柱把下面k個盤子挪到d柱
+通過ac柱把b上面的n-k個盤子挪到d柱
我們假設四柱挪n-k盤子的步數需要f[n-k]
又,我們熟悉三柱漢諾塔挪動n個盤子需要步數2^n-1
因此,對於每乙個k,我們有:
long
long temp=
2*f[x-k]
+pow(2
,k)-
1
此時我們只需要對每乙個k進行列舉,得到使得f[n]取到最小值的k,並得到f[n]即可
可以通過如下**片段實現:
f[0]
=0; f[1]
=1; f[2]
=3;for
(int x=
3;x<=n;x++)}
f[x]
=maxn;
}
整體**如下:
#include
#include
#define max 1000000
intmain()
;int maxn;
scanf
("%d"
,&n)
; f[0]
=0; f[1]
=1; f[2]
=3;for
(int x=
3;x<=n;x++)}
f[x]
=maxn;
}printf
("%d"
,f[n]);
}
當我們輸入資料測試,我們可以發現在n值大於等於63時,會有如下結果:
其原因是long long型別最多可以存放64位元組的資料,當資料過大,資料發生溢位。
可是在n=62時,f[n]的數值根本就不大,因此此處還有很大的優化空間。我們通過迴圈輸入,找其中的規律,**如下:
#include
#include
#define max 1000000
intmain()
;int maxn;
f[0]
=0; f[1]
=1; f[2]
=3;for
(int x=
3;x<=
63;x++)}
f[x]
=maxn;
}while(~
scanf
("%d"
,&n)
)}
測試各組數,尋找規律:
n每增加1,f[n]的值增加2^i
其中i以j為週期逐次加一
每個週期結束後j也會加一
因此我們根據規律,可以寫出執行速度更快的優化後的**如下:
#include
#include
intmain()
;for
(int a=
1;a<=
100;a++)
output[a]
=output[a-1]
+pow(2
,i-1);
}while
(scanf
("%d"
,&k)
!=eof
)}
此種演算法適用於更大數字的漢諾dd塔問題,但是也有計算的極限,可以通過大數字的逐位計算解決,實現起來也非常簡單,這裡不做贅述 四柱漢諾塔
多柱漢諾塔的解析 題目鏈結 分析 現在有四根柱子a b c d,我們假設盤子從a移動到d,先把a的n個盤子拿出r個借助其他兩個柱子放到b上這是f n r 接著這個柱子就先不動,然後開始動a上剩下的r個盤子,現在b已經不能放這r個,我們只能通過c柱子把r個移動到d上去。這裡只用到了c柱子和目標柱子,所...
四柱漢諾塔 1559
題目描述 漢諾塔 是乙個眾所周知的古老遊戲。現在我們把問題稍微改變一下 如果一共有4根柱子,而不是3根,那麼至少需要移動盤子多少次,才能把所有的盤子從第1根柱子移動到第4根柱子上呢?為了程式設計方便,只需要輸出這個結果除以10000的餘數。輸入描述該題含有多組測試資料,每組乙個正整數n。0輸出描述乙...
怎麼理解漢羅塔問題 漢諾塔問題(三柱及四柱)詳解
漢諾塔 hanoi tower 又稱河內塔,傳說大梵天創造世界的時候做了三根金剛石柱子,在一根柱子上從下往上按照大小順序摞著64片 圓盤。大梵天命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。並且規定,任何時候,在小圓盤上都不能放大圓盤,且在三根柱子之間一次只能移動乙個圓盤。問應該如何操...