河内双塔(递归+记忆化搜索)

        河内双塔由经典的汉诺塔问题演变而来,双盘的增加并没有改变盘子的转移策略:仍然是,先借助目标盘把原盘上除了最大的两个盘子 移动至中间盘,再将原盘底部最大的两个盘子移动至目标盘,之后借助原盘将中间盘的所有盘子移动至目标盘;可直接采用单盘转移的写法,结果乘以2即可

        但这需要注意数据范围,递归体每次进入需要要进入两层,题目范围1-50,最坏执行2^50次,会超时,需要做个简单的优化。递归式的写法其实很多计算点都是重复的,可采用记忆化搜索,初始化f[55] = {0}, 如果f[i]不等于0就是被计算过的点,直接返回f[i],不进入递归体,可以大幅低复杂度。写法如下:

#include <iostream>

using namespace std;

typedef long long LL;

LL f[55];

LL hannuo(char sou, char temp, char des, int n)
{
    if (f[n]) return f[n];
    
    f[n] += hannuo(sou, des, temp, n - 1);
    f[n] ++ ;
    f[n] += hannuo(temp, sou, des, n - 1);
    return f[n];
}

int main()
{
    int n;
    cin >> n;
    
    f[1] = 1;  // 初始化1个圆盘的转移次数
    
    cout << 2 * hannuo('a', 'b', 'c', n) << endl;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值