• 汉诺塔


    汉诺塔问题是一个经典的递归问题,大意是:有A, B, C三根柱子,A柱上有n个盘子,小的在上,大的在下,现在要在B柱的帮助下将A柱上的所有盘子移动到C柱上,而且要求每次只能移动一个,并且任何时候小的盘子只能在大的盘子上面。





    利用递归逐步分解问题的思想可以轻松解决这道题。首先考虑只有一个圆盘(n=0)的情况,之间从A移动到C即可;对于n个圆盘的情况,可以分解为3步:首先把上层 n-1 个圆盘移到B柱,然后把A柱上的1个圆盘移到C柱,最后把B柱上的 n-1 个圆盘移到C柱,完成移动。所以问题就变成了 n-1 个柱子移动的问题,以此类推,直到回到最初的移动一个圆盘的时候。Python实现的代码如下:

    def move(n, a, b, c):   
        if n == 1:
            print(a, ' --> ', c)
            return
        move(n-1, a, c, b)
        move(1, a, b, c)
        move(n-1, b, a, c)
        return
    
    #结果如下:
    >>> move(3, 'A', 'B', 'C')
    
    A  -->  C
    A  -->  B
    C  -->  B
    A  -->  C
    B  -->  A
    B  -->  C
    A  -->  C


    根据上述分析,第n个盘子需要把其上n-1个移走,然后底座1个移去目的地,最后把n-1个移过来,可以得出移n个盘子的所需的次数 f(n )= f(n-1)* 2 + 1,解出来后 f(n)= 2^n - 1。古老传说中大梵天让婆罗门移动上有64片黄金圆盘的汉诺塔,计算一下,需要移动 2^64 - 1 次,就算一次一秒,完成也需要约5846亿年,可怕!


    总结:我们可以看到,在解决这个问题的时候,如果纠结于每一个圆盘的移动,就会很复杂,但如果能够站在高处,不拘于细节而是把整个过程分解为几个大的部分,就能逐渐转化为更简单的问题。在思考递归的时候,可以将其当作一个黑盒来看待,而不必进入递归内部,否则容易越陷越深。

  • 相关阅读:
    (unix domain socket)使用udp发送>=128K的消息会报ENOBUFS的错误
    HTTP KeepAlive模式
    Windows 7 中的 God Mode
    我的开发环境配置经验
    C#格式化数值结果表(格式化字符串)
    我可怜的笔记本电脑
    JetBrains ReSharper 5.x 注册机
    异常处理准则
    调用 Windows 7 中英文混合朗读
    oracle笔记(2010130)
  • 原文地址:https://www.cnblogs.com/zhayujie/p/7534849.html
Copyright © 2020-2023  润新知