zoukankan      html  css  js  c++  java
  • BZOJ 1019: [SHOI2008]汉诺塔 简要证明

    先安利一发Sengxian的题解

    我看了好几篇博客,几乎就两种做法:一种是跟Sengxian的做法类似的或一样的,用递推关系求^o^另一种比较玄学的是猜通项公式( ̄▽ ̄)(其实是待定系数啦)

    当然我比较喜欢递推的做法,毕竟通项公式不好证明正确性(也可能是我没有多想想(´▽`))

    这里先多扯一句,汉诺塔又叫河内塔,而河内是越南首都,然而河内塔问题源于一个印度传说(´・_・`)

    这篇文章就是解决一个很简单的问题:怎样证明题目中说的“上述策略一定能完成汉诺塔游戏”?

    单纯的看,这个问题好像没有很好的思路来想。作为一个长期滑水选手当然先看了题解然后切掉这题再回头想这个问题。

    不过当我照着题解看明白思路后,证明就是很显然的了。

    题解一句话总结:g代表终点柱子,f代表步数。两种情况递推。

    既然要递推,就要处理好边界情况。这题的边界就是只有一个碟子的情况。步数是1,无论采取什么优先策略都有解^_^

    两个碟子的情况,首先移开小碟子到a。大碟子这时在b,下一步只能把大碟子移到c。下面移动小碟子。按照优先级小碟子要么移到b要么移到c。如果移到c的话,就完了。如果移到b的话,大碟子从c回到a,小碟子按照第一步的优先级从b到a。于是两个碟子是有解的。有解的含义不仅是可以确定移动方式,也可以确定数组g和f的值。

    (如果上面的一串已经把你搅晕了,那么请再看一遍^_^)

    下面就是正经的归纳了:

    假设问题在n=k时有解。当n=k+1时,按照Sengxian的解法,可以在n=k有解的基础上构造一组移动方式,使得k+1个碟子也可以移动到不同于初始柱子的碟子上。即n=k+1时也有解。

    这样,就通过归纳证明了“上述策略一定能完成汉诺塔游戏”。

    当然细心想想还是没有完。怎么证明Sengxian的构造法是正确的呢?这题是有优先级的限制,所以不是按照我们的想法随意移动最大的碟子,但通过问题的性质可以发现按照规则可以移动到需要的地方。按照规则,小碟子不能移动两次,只有大碟子可以移动一次。

    我猜这题的证明过程已经解释得很清楚了。

    %%%Sengxian%%%

  • 相关阅读:
    【C++17】std::optional

    【GDB 】GDB基本命令
    【二叉树系列 | 01】二叉树遍历
    【coredump | 01】coredump的阐述
    【C++ Template | 06】std::enable_if和SFINAE
    std::dclval 使用教程
    系统设计实践(03)- Instagram社交服务
    系统设计实践(02)- 文本存储服务
    系统设计实践(01)
  • 原文地址:https://www.cnblogs.com/HailJedi/p/9172617.html
Copyright © 2011-2022 走看看