对hanoi问题的理解

首先,我谈一下自己对原版hanoi问题递归公式的推导。
优秀的理解网址,有图形
我按照他的,也就是将A上的n个圆盘(编号从下往上是n->1)通过B移动到C。
首先,在什么也不知道的情况下,我自己模拟一下,来发现规律(不会画图,自己在草稿本上画吧)。
首先是1->C,2->B,然后就是1->B(先不要直接1->A,否则不利于找出子过程),现在的情况是A:n->3,B:2->1,C没有.然后就发现(有一种直接用n=1,n=2,n=3来发现子过程),就是将1->n-1先移动到B,然后将n移动到C,此时C相当于空的(因为最大的在下面)然后将剩余的1->n-1通过中间C移动到B,最后的递归条件就是n=1.
通俗地讲就是,现将最大的那个移动到C,这就现要求将上面的1->n-1先移动到B。然后C相当于空的,所以此时,规模为n-1的问题与原问题形式一样,全部在一个柱子上,然后通过一个空的柱子,全部移动到另外一个柱子上。然后就可以递归了。知道规模缩小到n=1,虽然我并不知道,具体如何将1->n-1移动到C。

 public static void hanoi(int n,char A,char B,char C)
    {
        if(n == 1)//圆盘只有一个时,只需将其从A塔移到C塔
            TowersOfHanoi.move(1, A, C);//将编b号为1的圆盘从A移到C
        else
        {//否则
            hanoi(n - 1, A, C, B);//递归,把A塔上编号1~n-1的圆盘移到B上,以C为辅助塔
            TowersOfHanoi.move(n, A, C);//把A塔上编号为n的圆盘移到C上
            hanoi(n - 1, B, A, C);//递归,把B塔上编号1~n-1的圆盘移到C上,以A为辅助塔
        }
    }

然后就是对代码的理解,函数的声明意思是:现在规模为n的hanoi(相当于A:1->n,B:0,C:0),将A上的n个圆盘通过B移动到C.
函数内部的理解:首先是递归结束条件。然后:三个核心子过程,将1->n-1从目前认为的A(等价意义,比如现在的C相当于原来的A)通过C移动到B,然后将最下面的n从A移动到C,最后将1->n-1从B通过A移动到C。
至于n=x时要操作多少次,可以打表观察规律,也可以理论分析出来。
这个对思维能力还是要求比较高,不过还是递归蛮有意思,将一个复杂问题简单化。
hanoi变式题-HDU集锦

问题归约法是一种将复杂问题转化为若干个较简单子问题的方法。在Hanoi问题中,其原理、方法及应用如下: ### 原理 使用“分治”方法解决规模为 n 的问题,需将其表示为多个规模为 (n - 1) 的同类型子问题的组合。对于规模为 0 或 1 的问题,需有直接解。在Hanoi问题里,要把 n 个金片从一个宝石针移动到另一个宝石针,可将其归约为多个移动 n - 1 个金片的子问题。这是因为解决大规模的Hanoi问题可以依赖于解决小规模的Hanoi问题,符合分治的思想,即把一个大问题分解为多个相似的小问题来求解 [^3]。 ### 方法 以汉诺塔问题为例,移动金片的次数 f(n) 与宝石针上的金片个数 n 之间存在一定关系。将 n 个金片从起始针借助中间针移动到目标针,可分解为以下三个子问题: 1. 把 n - 1 个金片从起始针移动到中间针。 2. 把第 n 个金片从起始针移动到目标针。 3. 把 n - 1 个金片从中间针移动到目标针。 通过这样的归约,原本复杂的移动 n 个金片的问题就转化为了多次移动 n - 1 个金片的问题,不断重复这个归约过程,直到问题规模变为 1 或 0,此时有直接解,即当只有 1 个金片时,直接将其从起始针移动到目标针即可 [^2][^3]。 ### 应用 通过计算可知,汉诺塔问题移动金片的次数,f(n) 与宝石针上的金片个数 n 之间存在特定关系。并且,汉诺塔问题递归算法的时间复杂度为 O(2^n),这表明随着金片个数的增加,移动次数呈指数级增长。在实际应用中,问题归约法帮助我们把看似复杂的汉诺塔问题转化为可处理的子问题,从而可以编写递归程序来解决该问题。同时,在教学中,汉诺塔问题是介绍递归概念常用的案例,通过计算和分析汉诺塔问题,能让学生更好地理解递归和分治的思想,提高学生的计算思维能力 [^1][^2]。 ```python def hanoi(n, source, auxiliary, target): if n == 1: print(f"Move disk 1 from {source} to {target}") return hanoi(n - 1, source, target, auxiliary) print(f"Move disk {n} from {source} to {target}") hanoi(n - 1, auxiliary, source, target) # 测试 n = 3 hanoi(n, 'A', 'B', 'C') ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值