HDU2077 汉诺塔IV 递推做法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Neo_kh/article/details/81254374

HDU2077 汉诺塔IV

原题链接在此:HDU2077
这道题目会用到HDU2064汉诺塔III的递推式,可以参考我的另一篇博客:汉诺塔III
本问题和III的区别在于最后一个圆盘,但恰恰因为最后一个圆盘,之前的思路需要大的改动(因为我们不知道最后一块圆盘到底是第几块)。
假设变量:
- 设a[i]为将第i块圆盘从左边移动到右边(或从右到左)的步数;
- b[i]为将第i块圆盘从左边移动到中间(或从右到中间,或从中间到左、右)的步数;
- c[i]为如果i为最后一个圆盘,一共所需要的步数

分析思路如下:

  • 将前 n-1 个圆盘移动到中间柱子上
  • 把第 n个盘子移到中间再移到右边
  • 最后把中间 n-1个圆盘移到右边

以上三行总结的公式:c[n]=2*b[n-1]+2 ;
现在我们需要求b[i]:

  • 先把前i-1个从左边移到右边
  • 再把第i个圆盘移到中间
  • 最后把前i-1个从右边移到中间

以上总结出的公式为:b[i]=a[i-1]+b[i-1]+1;
现在我们需要求a[i],而求a[i]的方式在汉诺塔III的博客里面,不再赘述。


实现代码

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

猜你喜欢

转载自blog.csdn.net/Neo_kh/article/details/81254374