【杭电oj】2077 - 汉诺塔IV(递推)

点击打开题目

汉诺塔IV

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

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

 

Input 输入数据的第一行是一个数据T,表示有T组数据。

每组数据有一个正整数n(1 <= n <= 20),表示有n个盘子。

 

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

 

Sample Input

2 1 10  

Sample Output

2 19684  

Author xhd  

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

仍然是汉诺塔问题,这次的变形是最大的可以随意移动。

这次的 hanoi 数据记录的是移动到相邻杆子上所需的次数。

1的时候为1,2的时候,需要在1的基础上,把1移动 到最右边,2放到中间,1再移动回来,则:hanoi [ 2 ]  = hanoi [ 1 ] + hanoi [ 1 ] * 2 + 1;

……类推一下,得出递推公式:hanoi [ n ] = hanoi [ n – 1 ] * 3 + 1;

然后再考虑题目,可以把最大的移动到小的上面,那么先把上面 n – 1 个移动到中间,再把最大的移动到最右边,再把那 n – 1 个移动到最右边,Game Over~

所以得出结果:ans = hanoi [ n – 1 ] * 2 + 2;

代码如下:

#include <cstdio>
int main()
{
    __int64 hanoi[22];        //把n个移到相邻杆子所需次数 
    hanoi[0] = 0;
    hanoi[1] = 1;
    for (int i = 2 ; i <= 19 ; i++)
        hanoi[i] = hanoi[i-1] * 3 + 1;
    int u;
    scanf ("%d",&u);
    int n;
    while (u--)
    {
        scanf ("%d",&n);
        printf ("%d\n",2*hanoi[n-1]+2);
    }
    return 0;
}
    原文作者: 汉诺塔问题
    原文地址: https://blog.csdn.net/wyg1997/article/details/51746907
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞