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