zoukankan      html  css  js  c++  java
  • 萌新笔记之Nim取石子游戏

    以下笔记摘自计算机丛书组合数学,机械工业出版社。

    Nim取石子游戏

    Nim(来自德语Nimm!,意为拿取)取石子游戏。

    前言:

    哇咔咔,让我们来追寻娱乐数学的组合数学起源!

    游戏内容:

    有两个玩家面对若干堆东西(硬币,石子,豆子···)进行游戏。设有k≥1堆硬币,各堆分别含有n1,n2...nk枚硬币。
    游戏规则:

    (1):游戏中两个人交替进行游戏(我们称第一个取的为1号,第二个取的为2号)。

    (2):当玩家取石子的时候,先选择硬币中的一堆,然后可以从堆中取走任意数量的硬币。

    当所有的堆为空时,游戏结束。最后取子者(即能够取走最后一堆中剩下的所有硬币)获胜。

    注意:游戏是明智进行的,即两个玩家都是以自己最优进行的。What should I do?我也很无奈呀。

    不要纠结就是上呀:

    我们先考虑特殊情况(这是一般求解问题的重要原则:为了深入理解呵强化直觉力,往往考虑小的或特殊清形。然后,为了一般地解决问题再努力扩展你的想法,感觉这个对构造问题也是很有帮助)。

    特殊情况:

    如果一开始只有一堆(n1):那么1号取完n1,win,游戏结束。

    如果一开始只有两堆(n1,n2):那么对于1号来说,他不关心n1,n2,他关心的是n1,n2是否相等。

    如果n1≠n2,那么1号取多的那一堆,使得两堆相等,等2号来取的时候,2号取完只会产生两种情况:①:存在两堆不相等 ②:只有一堆了。

    对于②:一号win,游戏结束。

    对于①,一号继续构造成两堆相等,一直如此,会变成状态②,一号win.


    讲到这里还是蛮简单的嘛~


    好,我们去考虑一般情况!拿起纸和笔一起啊~

    哦,等等我说个过渡,太直接感觉不好。

    过渡:

    我们知道对于一个十进制数,都有一个对应的二进制数,比如11:1011。我把每堆分成几个子堆(其实没分!其实没分!其实没分!只是我们假想分了!),怎么分呢?

    就是应用刚刚说的拆成2的非负次幂的数[1(2^0),2(2^1),4(2^2)....2^x],11就拆成了8+2+1=11.

    有什么用呢?

    在2-堆 Nim取石子游戏中,各种大小的子堆的总数只能是0,1,2(废话,总共只有2堆)。

    考虑各种大小的子堆的总堆数是偶数是什么情况?那么不就是两个堆相等嘛,2号赢的情况!我相信,在这里感觉来了,如果前提不是2-堆而是k-堆,而各种大小的子堆的总堆数都是偶数?(希望我不是沉浸在自己的世界里)

    重点:

    现在考虑各堆大小为n1,n2...nk的一般Nim取石子游戏。将每一个数ni表示成2的非负次幂的数(11->1011)


    我们说(不是我说的,是数学家说的)Nim取子游戏是平衡的。(这里跨度有点大,但是感觉这里还是自己理解就好。)

    于是我们有1号能够在非平衡Nim取子游戏中取胜,2号能够在平衡Nim取子游戏中取胜。
    如果局势是非平衡的状态,那么1号可以从一个堆中取石子,留给2号平衡的状态。而2号怎么做都会构成非平衡状态,从而1号win;反之,同理。

    我们举个例子有4个堆:7,9,12,15

    堆大小 2^3=8 2^2=4 2^1=2 2^0=1
    7 0 1 1 1
    9 1 0 0 1
    12 1 1 0 0
    15 1 1 1 1
    显然是非平衡的,3位,2位,0位非平衡,也就是1号会赢。
    那么也就是说1号怎么搞构造成平衡呢?

    有:

    从12选11,剩:0001,满足

    从9取5, 剩:0100,满足

    从15取13,剩0010,满足

    that's all, thanks!


  • 相关阅读:
    字符输入输出
    每日一例
    每日一例
    结构
    指针数组的初始化
    装箱,拆箱,正则表达式
    数据类型的转换
    怎样让程序不断执行
    SQL练习1关于插入删除,修改,单表查询
    SQLSERVER 总结1
  • 原文地址:https://www.cnblogs.com/keyboarder-zsq/p/6777402.html
Copyright © 2011-2022 走看看