Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6070 Accepted Submission(s): 2966
1 3 12
1 5 81
一题比较经典的题;
思路:
首先我们会想到,三柱汉诺塔需要借助另一个柱子存放前n-1个盘子,再把第n个盘子移动到目的位置。
顺其自然的,四柱汉诺塔由于多了一个柱子,我们可以多留下一个盘子n-2,而不让它借位到其他柱子直接移动到目的位置。
算法的基本流程:
(1)从A借助C、D将 n-2个盘子移动到B上。
(2)将第n-2个盘子移动到C上。 (盘子从上到下编号0,1,2,3,4......,n-2,n-1)
(3)将第n-1个盘子移动到D上。
(4)将第n-2个盘子移动到D上。
(5)从B借助A、C将 n-2个盘子移动到D上。
按照以上设计的算法流程,我们得到递归方程:F(n)=2*F(n-2)+3。
因此得到移动步数为:F(n)=4*2^(n/2)-3:n为奇数;F(n)=6*2^(n/2-1)-3:n为偶数。
那到底对不对呢???
经过验证,显然是有问题的。不信你代入n=12 看看结果是什么就知道了。但是不管怎么样有这样的想法思路是好的;
#include<stdio.h> #include<algorithm> #define LL unsigned __int64 #define mmax 0x7fffffff using namespace std; LL ans[65]; LL ppow(LL a,LL b) { LL c=1; while(b) { if(b&1) c=c*a; a=a*a; b>>=1; } return c; } void hanoi() { ans[0]=0; ans[1]=1; ans[2]=3; for(int i=3;i<=64;i++) { ans[i]=mmax; for(int x=1;x<i;x++) { ans[i]=min(ans[i],(2*ans[x]+ppow(2,i-x)-1)); } } } int main() { int n; hanoi(); while(scanf("%d",&n)!=EOF) { printf("%I64u\n",ans[n]); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/u010579068/article/details/46894897