HDU 2077 汉诺塔IV

来源:互联网 发布:淘宝店铺层级怎么计算 编辑:程序博客网 时间:2024/04/26 03:52

汉诺塔IV

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


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

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

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

Sample Input
2110
 

Sample Output
219684
 

Author
xhd
 

Source
ACM程序设计期末考试_热身赛(感谢 xhd & 8600)
 

注意:

1:找出规律即可

把(n-1)个盘子从左边移到中间的移动最优规律:

把(n-2)个盘子 从左边移到中间 需要 f(n-1)次

把(n-2)个盘子 从中间移到右边 需要 f(n-1)次

把第(n-1)个盘子 从左边移到中间 需要1次

把(n-2)个盘子 从右边移到中间 需要 f(n-1)次

一共需要f(n)=3*f(n-1)+1次

此时相当于把(n-1)个盘子移到中间

然后:

把第n个盘子 从左边移到右边 需要移动2次

把(n-1)个盘子从中间移到右边又需要f(n)=3*f(n-1)+1次

所以:

一共需要移动:ff(n)=2*f(n)+2次,其中f(n)=3*f(n-1)+1

 


 

#include<stdio.h>int main (void){    __int64 f[40],ff[40];    ff[1]=2;    ff[2]=4;    f[3]=4;    int i,n,m;    for(i=4;i<=38;i++)    {        f[i]=3*f[i-1]+1;    }    for(i=3;i<=35;i++)    {        ff[i]=2*f[i]+2;    }    scanf("%d",&m);    while(m--)    {        scanf("%d",&n);        printf("%I64d\n",ff[n]);    }    return 0;}


 

 

0 0