HDU 2064 汉诺塔III

来源:互联网 发布:网络名誉权侵权起诉书 编辑:程序博客网 时间:2024/04/27 15:50

在做UVA10795新汉诺塔问题前,我决定先去把汉诺塔给熟悉一下。

我还没做过呢T T

第一次接触汉诺塔貌似是谭浩强的C语言里面的递归。(小小吐槽一下他的书)

言归正传,

这题与常规的不一样在于:不允许直接从最左(右)边移到最右(左)边(每次移动一定是移到中间杆或从中间移出)

先回想一下常规的题:(允许直接从A到C)

从左到右设为A、B、C,因为可以直接从A移动到C,所以只需要N-1到B,N到C,要达到目的还要N-1到C(这里N指第N个盘子,N-1指1~N-1个盘子,下同)

它的递推式为:

 a[1] = 1;

 a[n] = a[n-1] * 2 + 1;

可以验证:

a[n]= 2^n-1;

 

这题呢?其实也很简单,同样的,从左到右设为A、B、C因为不能从A直接移动到C,那么把第N个盘子移动到C时,必有N在B,所以把N-1个盘子移动到C之后,还要移动回A。

那么就是这样N-1移动到C,N到B,N-1到A,N到C,N-1到C

显然,它的递推式为:

a[1] = 2;

a[n] = a[n-1] *3 + 2;

注意上下两个的对比。

然后我就猜想:

a[n]= 3^n-1?

答案是肯定的。

用数学归纳法证明如下:

1.      n=1是显然成立

2.      设n=k时,等式成立;那么有a[k]= 3^k-1    a[k]=a[k-1]*3+2

3.      n=k+1时a[k+1]=a[k]*3+2=(3^k-1)  *3+2=3^(k+1)-3+2=3^(k+1)-1

证毕:)

 

所以代码如下:(HDU不支持%lld好吧。。。难道是我抛弃VC6的后果么,换个OJ各种悲T T)

 PS(用pow WA的原因在于 double可表示的范围比long long 小)

#include <iostream>using namespace std;int main(){int n;while(scanf("%d",&n)!=EOF){long long x=1;for(int i=0;i<n;i++)x*=3;printf("%I64d\n",--x);//HDU不支持lld么。。//cout<<--x<<endl;}}


原创粉丝点击