HDU 2064 汉诺塔III

在做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;
	}
}


转载于:https://www.cnblogs.com/murmured/p/5004336.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值