UVA 10795 新漢諾塔問題(遞迴)

2021-10-01 19:54:35 字數 1265 閱讀 5073

題目:

新漢諾塔問題往舊漢諾塔問題上轉換,所以先來看舊漢諾塔問題。

舊漢諾塔:

漢諾塔問題是乙個經典的問題。漢諾塔(hanoi tower),又稱河內塔,源於印度乙個古老傳說。 大梵天創造世界的時候做了三根金剛石柱子,在一根柱子上從下往上按照大小順序摞著64片**圓盤。

大梵天命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。

並且規定,任何時候,在小圓盤上都不能放大圓盤,且在三根柱子之間一次只能移動乙個圓盤。

問應該如何操作?

既然是個遞推問題,那就從大到小的依次找圓盤,若想把第n個圓盤放到第i根柱子上,首先保證,第i根柱子上沒有比n小的盤子,

且n上面也無任何圓盤,所以這時候才能把n放到第i根柱子上。依次類推到第1個盤子。

在寫遞推函式的時候要逆著寫,不要順著往下想,比如在考慮n的情況的時候,要先想第n-1個情況已經完成了,這時候n該幹什麼了,這個函式的是為n-1後n的情況進行的治理,所以也是分治情況的一種。

所以該這樣實現:

#includeusing namespace std;

void hannuo(int n,char first,char middle,char end)

int main()

再來看新漢諾塔問題,由於一開始情況未知,所以要往舊漢諾塔問題上轉換,

初始局面和目標局面移動到參考局面的和加1就是結果。

所以f(start,n-1,other)表示初始局面到參考局面,

參考局面到目標局面是針對於第n-1個盤子來說的,因為移動可逆,也可以想成是目標局面到參考局面,這麼想只是為了

函式更好的實施。

所以目標局面到參考局面f(finish,n-1,other).

這個時候每個單獨的f(),就轉換成了舊漢諾塔問題,而舊漢諾塔問題中,每把n個柱子移動到另乙個柱子上,需要的

步是2^i-1步。

這個問題就因此解決了

實現:

#includeusing namespace std;

const int maxn=65;

typedef long long ll;

int n;

int start[maxn],finish[maxn];

long long f(int *p,int i,int final)

int main()

printf("case %d: %lld\n",++kase,ans);

} return 0;

}

遞迴 新漢諾塔

時間限制 1 sec 記憶體限制 128 mb 題目描述 設有n個大小不等的中空圓盤,按從小到大的順序從1到n編號。將這n個圓盤任意的 迭套在三根立柱上,立柱的編號分別為a b c,這個狀態稱為初始狀態。現在要求找到一種步數最少的移動方案,使得從初始狀態轉變為目標狀態。移動時有如下要求 一次只能移乙...

漢諾塔問題

問題 假設有3個分別命名為x,y,z的寶塔,在塔座x上插有n個直徑大小各不相同,從小到大編號為1,2,3。n的圓盤。現要求將x軸上的n個圓盤移至塔座z上 並仍然按同樣的順序疊排,圓盤移動時必須遵循下列規則 1.每次只能移動乙個圓盤 2.圓盤可以插在x,y和z中的任一塔座上 3.任何時刻都不能將乙個較...

漢諾塔問題

問題是 印度的乙個古老的傳說。開天闢地的神勃拉瑪在乙個廟裡留下了三根金剛石的棒,第一根上面套著64個圓的金片,最大的乙個在底下,其餘乙個比乙個小,依次疊上去,廟裡的眾僧不倦地把它們乙個個地從這根棒搬到另一根棒上,規定可利用中間的一根棒作為幫助,但每次只能搬乙個,而且大的不能放在小的上面。解答結果請自...