HDU 2077 汉诺塔IV

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2077

汉诺塔IV

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4332    Accepted Submission(s): 3187


Problem Description
还记得汉诺塔III吗?他的规则是这样的:不允许直接从最左(右)边移到最右(左)边(每次移动一定是移到中间杆或从中间移出),也不允许大盘放到小盘的上面。xhd在想如果我们允许最大的盘子放到最上面会怎么样呢?(只允许最大的放在最上面)当然最后需要的结果是盘子从小到大排在最右边。
 

Input
输入数据的第一行是一个数据T,表示有T组数据。
每组数据有一个正整数n(1 <= n <= 20),表示有n个盘子。
 

Output
对于每组输入数据,最少需要的摆放次数。
 

Sample Input
  
  
2 1 10
 

Sample Output
  
  
2 19684
这道题还挺有趣的,有点难度的,我就解释一下。

注意,除了大盘能放在小盘上面,只能是最大的盘可以其它比它小的盘子上面。

首先,为了方便描述,将三根柱子分别编号为A,B,C,A柱子上的盘子号从上往下依次编号为1,2,3,4,,,n.

f(n)表示把A柱子上的n个盘子借助其它柱子搬到C柱子上去需要的步数。

g(n)表示把某个柱子上的n个盘子借助其它柱子搬到相邻柱子上去需要的步数。

对于A柱子上的n个盘子,先将上面的n-1个盘子借助其它柱子搬到B柱子上去。需g(n-1)步,然后由于A柱上的n号盘是最大的盘子,故A柱子的n号可以移到B柱子上,继而移动到C柱子,共2步。最后把B柱子上的n-1个盘子借助其它柱子移动到C柱子整个过程就完成了。

可得f(n)=2*g(n-1)+2;

可是g(n)我们也不知道啊。

这g(n)不正是与汉诺塔III类似的吗?

下面推导g(n)

g(1)=1

g(2)=3+1=4

g(3)=3*g(2)+1

g(n)=3*g(n-1)+1;

g(n)可以预处理求出

接下来f(n)=2*g(n-1)+2就方便求出了。

下面是AC代码

#include<cstdio>
int main()
{
    int n,a[100]={0,1},t;
    for(int i=2;i<=20;i++) a[i]=3*a[i-1]+1;
    scanf("%d",&t);
    while(t--) scanf("%d",&n),printf("%d\n",2*a[n-1]+2);
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值