汉诺塔变种(邻近柱子才可移动)

汉诺塔变种(邻近柱子才可移动)

原题网址:http://acm.hdu.edu.cn/showproblem.php?pid=2064

汉诺塔问题是典型的递归问题,解决递归问题的两个核心条件是:

  1. 原始问题转化为规模更小的子问题
  2. 找到递归出口(结束更深层次递归的条件)

原始的汉诺塔问题要求一共三根杆,将最左边的杆上的圆盘全部转移到最右边的杆子上,其它基本限制不过多赘述。

该汉诺塔变种要求盘子只能在相邻的柱子之间移动,而不能直接从第一个柱子移动盘子到第三个柱子上,或从第三个柱子上直接移动到第二个柱子上。要求移动的最少次数。

子问题转化

该变种的子问题转化思路如下:

​ 假设将n个盘子从第一个柱子转移到第三个柱子所需要的移动总次数是f(n)。将现有的n个盘子看做两个部分,最下面的大盘子为一部分,大盘子上面的n-1个盘子为一部分,先将大盘子上的n-1个盘子移动到第三个柱子(这里已经出现了原问题的子问题了,这个过程的移动次数和单纯的将第一个柱子上的n-1个盘子移动到第三个柱子,即f(n-1)是等价的),这一步的移动次数是f(n-1);之后将最下面的大盘子从第一个柱子移动到第二个柱子,移动一次;接下来将第三个柱子上的n-1个柱子从第三个柱子上移动到第一个柱子上,这里又是一个f(n-1);之后将第二个柱子上的大盘子移动到第三个柱子上,移动一次;最后将第一个柱子上的n-1个盘子移动到第三个柱子上,又是一个f(n-1)。至此,从最表层看,任务已经完成了。最终可以得到一个递推公式如下:
f ( n ) = 3 f ( n − 1 ) + 2 f\left( n \right) =3f\left( n-1 \right) +2 f(n)=3f(n1)+2

递归出口

递归到最深处,当n=1,就只需要两步,即f(1)=2。

代码

#include <iostream>
using namespace std;

long long Hanoi(int n){
    if(n==1){
        return 2;
    }
    else
        return 3*Hanoi(n-1)+2;
}
int main() {
    int n;
    while(scanf("%d",&n)!=EOF){
        cout<<Hanoi(n)<<"\n";
    }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值