漢諾塔II
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 6 Accepted Submission(s) : 3
Problem Description
經典的漢諾塔問題經常作為一個遞歸的經典例題存在。可能有人並不知道漢諾塔問題的典故。漢諾塔來源於印度傳說的一個故事,上帝創造世界時作了三根金剛石柱子,在一根柱子上從下往上按大小順序摞著64片黃金圓盤。上帝命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。並且規定,在小圓盤上不能放大圓盤,在三根柱子之間一回只能移動一個圓盤。有預言說,這件事完成時宇宙會在一瞬間閃電式毀滅。也有人相信婆羅門至今仍在一刻不停地搬動著圓盤。恩,當然這個傳說並不可信,如今漢諾塔更多的是作為一個玩具存在。Gardon就收到了一個漢諾塔玩具作為生日礼物。
Gardon是個怕麻煩的人(恩,就是愛偷懶的人),很顯然將64個圓盤逐一搬動直到所有的盤子都到達第三個柱子上很困難,所以Gardon決定作個小弊,他又找來了一根一模一樣的柱子,通過這個柱子來更快的把所有的盤子移到第三個柱子上。下面的問題就是:當Gardon在一次游戲中使用了N個盤子時,他需要多少次移動才能把他們都移到第三個柱子上?很顯然,在沒有第四個柱子時,問題的解是2^N-1,但現在有了這個柱子的幫助,又該是多少呢?
Input
包含多組數據,每個數據一行,是盤子的數目N(1<=N<=64)。
Output
對於每組數據,輸出一個數,到達目標需要的最少的移動數。
Sample Input
1
3
12
Sample Output
1
5
81
主要是討論,將一部分按四根柱子的最優方法移到一根柱子上,其余的按三根柱子的最優方法移到指定位置,再將那些移上去,通過循環找出最優。
AC代碼如下:
#include
#include
using namespace std;
__int64 erdemi(__int64 a)
{
__int64 i,sum=1;
for(i=1;i<=a;i++)
sum*=2;
return sum;
}
int main()
{
__int64 n,i,j;
__int64 a[70],min;
a[1]=1;a[2]=3;a[3]=5;a[4]=9;
for(i=5;i<=64;i++)
{
min=2*a[i-1]+1;
for(j=2;j<=i/2;j++)
{
if(2*a[i-j]+erdemi(j)-1>n)
{
cout<