编程之美----NIM(4)

原帖地址:http://blog.sina.com.cn/s/blog_7689f89d01017u6y.html

题目:两个玩家,只有一堆石头,两人一次拿石头,最后那光者为赢家。取石头的规则是:
            1、第一个玩家不能拿光所有的石头。
            2、第一次拿石头之后,每人每次最多只能拿掉对方前一次所拿石头的两倍。
      那么,这个游戏有没有必胜的算法?(提示:好像和Fibonacci数列有关。)


解答:

  1. 根据题目后面的提示,当石头数N=F(n)——F(n)为 Fibonacci 数列,先手输;其余情况先手赢。(如果没有提示,我是想不出该结论的,因此我写的只是该结论的证明而已)
  2. 还是用数学归纳法,明显当N=2,3,该结论成立(N=1,游戏玩不了)。
  3. 现假设N=F(k),结论成立。先证明N=F(k)+i<F(k+1),先手能赢。
  4. 显然,i<F(k+1)-F(k)=F(k-1),假如i<=F(k-2),则先手直接取i颗石头,留下F(k)颗给后手,因为2*i<=2*F(k-2)<F(k-2)+F(k-1)=F(k),所以后手无法一次性拿掉F(k)颗,又根据假设,该情况后手输,所以先手赢;
  5. 假如F(k-2)<i<F(k-1),则先手的策略是先取i-F(k-2),然后再让后手取F(k-2)。其中,如果i-F(k-2)也是Fibonacci数,则i-F(k-2)最大为F(k-4)(读者可自己证明),先手完全可以一次性取完,因为2*F(k-4)<F(k-2);如果i-F(k-2)不是 Fibonacci数,由前面假设可以得知最终也是先手取完,因为先手最终取的石头数目必定小于 i-F(k-2)的最大 Fibonacci数,即F(k-4),因此不用担心后手能一次取完F(k-2)。
  6. 证明N=F(k+1),先手输。
  7. 先手想不输,则不能将赢面留给后手,所以先手第一次至少拿F(k-1),留给后手F(k),可是根据规则,此时后手最多能拿2*F(k-1)颗石头,由于2*F(k-1)>F(k-1)+F(k-2)=F(k),因此,后手可以一次性拿掉剩余的F(k)颗石头,因此当N=F(k+1)时,先手必输。
  8. 证毕。
    原文作者:juary_01
    原文地址: https://blog.csdn.net/wm_1991/article/details/47154845
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞