HDU2077 汉诺塔四 难懂

#include <iostream>
#include <cmath>
using namespace std;
long long myPow ( int n , int e )
{
     long long mlt = 1;
     for ( int i = 1; i <= e ; ++ i )
     {
           mlt *= n; 
     } 
     return mlt;
}
int main ()
{
    int N;
    while ( cin >> N )
    {
          cout << myPow ( 3, N - 1 ) + 1 << endl;
    }
    return 0; 
}

//这个是网上的做法


因为最大的可以放在最上面, 所以就不能像 汉诺塔III那样把前n-1个盘全部从1->3了.

只要把前n-1个盘从1->2,然后把第n个盘1->2->3,然后把前n-1个盘2->3, 这样就完成了.

所以,问题现在转换成 n 个盘移动一步需要多少次.   我们可以看到, 除了最后一个最

大的盘n以外, 前n-1个盘的移动方式是和 汉诺塔III的规则是一样的.所以我们先把前

n-2 个盘 1->3, 然后把 第n-1个盘 1->2, 再把前n-2个盘 3->2, 这样就把前 n-1个盘

1->2 移动了一步.
因为把 n 个盘 按找汉诺塔III的方法 1->3 需要 3n -1 推导见 :

                              HDOJ HDU 2064 汉诺塔III ACM 2064 IN HDU 

所以由上面描述的步骤知道把 n 个盘移动一步需要 : f(n) = f(n-1) + ( 3n-1 - 1 ) + 1 = f (n-1) + 3n-1 而 f(1) = 1 
由递推式化简得: f(n) = 3n-1 + 3n-2 + ...+ 3 + 1 = ( 3n -1 ) / 2
所以按 汉诺塔IV的规则, 移动 n 个盘 需要 : m(n) = 2 * f (n-1) + 2 = 3n-1 + 1

还是不大明白直接加2 的原因
据说是。。。。。。同样是找规律,与hdoj2064题类似,只是n个圆盘移动,只要将n-1个圆盘依次移动,第n个圆盘在n-1个圆盘移动的过程中移动两次足矣,即移动次数F(n)=f(n-1)+2(f函数为2064题的函数,详见hdoj.2064#include<stdio.h>
int main()
{
    __int64 s[21],temp;
    int n,i,m;
    scanf("%d",&n);
    s[0]=0;
    s[1]=2;
    for(i=2;i<=20;i++)
    s[i]=(3*s[i-1]+2);
    while(n--)
    {
        scanf("%d",&m);
        temp=s[m-1]+2;
        printf("%I64d\n",temp);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值