HDU - 1207 汉诺塔问题二 (递归)

题目大意题目在这

  本来经典的汉诺塔问题是把盘子在三根柱子上移动,现在多了一根柱子,让你求有了这根柱子的帮助最少需要移动几步可以把盘子从一根柱子上完全移动到另一根柱子上。

题目思路:

  结合原来的经典汉诺塔问题,可以考虑到显然是一个递归问题,

     设F[n]为所求的最小步数,我们将移完盘子的任务分为三步:

   (1)将x(1<=x<=n)个盘从a柱依靠b,d柱移到c柱,这个过程需要的步数为F[x];

   (2)将a柱上剩下的n-x个盘依靠b柱移到d柱(注:此时不能够依靠c柱,因为c柱上的所有盘都比a柱上的盘小)这时移动方式相当于是一个经典汉诺塔,即这个过程需要的步数为2^(n-x)-1

   (3)将c柱上的x个盘依靠a,b柱移到d柱上,这个过程需要的步数为F[x];

     任务完成!!!

  可以看到,我们有很多种放法来移动,具体在那个x上,每次选择几个盘子呢?因为题目要求找出最小移动步数,所以我们可以遍历 0 < x < n得min { 2 * F [ x ] + 2 ^ ( n - x ) - 1};

题目代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#define INF 9999999
#define maxn 70

using namespace std;
long long f[maxn];

int main()
{
    int i,n,j;
    f[1]=1;
    f[2]=3;
    for(i=3;i<=64;i++)
    {
        int minn=INF;
        for(j=1;j<i;j++)
        {
            if(2*f[j]+pow(2,i-j)-1<minn)//找出最小的移动次数
                minn=2*f[j]+pow(2.0,i-j)-1;
        }
        f[i]=minn;
    }
    while(~scanf("%d",&n))
    {
        printf("%lld\n",f[n]);
    }
    return 0;
}

呼呼

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值