zoukankan      html  css  js  c++  java
  • 取石子游戏的策略及其应用

    有一种很有意思的游戏,就是有物体若干堆,可以是石子或是围棋子等等均可。两个人轮流从堆中取物体若干,规定最后取光物体者取胜。取石子游戏是我国民间流传已久的一种博奕,在国外亦称Nim游戏。别看这游戏极其简单,却蕴含着深刻的道理。下面我们来分析一下要如何才能够取胜。

    游戏Ⅰ 有若干堆任意数目的小石子{a1,a2,…,am}(m≥1),两人轮流取石子,每人每次可以从其中任意一堆中取,每次可以取1、2、3、……或k(1≤k≤ min{a1,a2,…,am})颗石子,把石子取完的人为胜者。

    采用符号{a1,a2,…,am;k}来代表游戏Ⅰ中小石子的初始状况和限制条件,一个人取一次石子实际上就是把{a1,a2,…,am;k}中某个分量ai(1≤i≤m)减小为ai′,即{a1,a2,…,ai,…,am;k}—→{a1,a2,…,ai′,…,am;k}(0≤ai<ai),我们把这种取一次石子使数组发生的变换称为T变换,根据现成博奕论先驱冯·诺伊曼(VonNeumann)的“完全确定信息游戏必定存在一种确定的获胜策略”的经典理论,要么对先取者存在某种取法,即某个T变换,无论后取者如何取,先取者总有相应对策,直至最终取得胜利;要么无论先取者如何取,后取者可以找到某种T变换,保证后取者总有相应策略获胜。为了解决游戏{a1,a2,…,am;k}的对策,我们先看一个简单的例子。

    例1 桌上放着一堆小石子一共100颗,两人(甲、乙)轮流取,每次可以取1至10颗,取完的人为胜者,怎样才能取胜?

    分析这个问题实际上是取石子游戏的特殊情形{100;10},我们利用倒推法:容易看出11是取胜的关键数学,因为到此时,不论对方(甲)取多少颗(大于0且小于11),总留下大于0且小于11颗石子,这样乙方一次取完即获得胜利。同样地分析,要取到11必须取到22,33,44,55,66,77,88,99,这样我们就知道了获胜之道:

    ①先取1颗石子,留下99颗,然后对方取a(1≤a≤10)颗,己方取(11—a)颗,就总能掌握这种致胜的关键数,从而确保获胜。②如果对方先取,己方只需利用对方不知道其中奥秘,争取到一个致胜数,就总能依①中方法取到下一个致胜数,最后取得胜利。实际上,如果局中人均熟知获胜策略,那么开局的局势就已经完全决定了结局的输赢,例1其实是先取者必胜的局势,从这个例子的分析过程我们得到启示:可以用同余理论来探讨一般情况。

    一般地,在取石子游戏{a1,a2,…,am;k中,ai≡ai′(modk+1)(i=1,2,…,m)其中0≤ai′≤k,在{a1′,a2′,…,am′;k}中有取胜策略的一方在{a1,a2,…,am;k}中也有取胜策略。证明 在{a1′,a2′,…,am′;k}中有获胜策略的一方,对于大于k的分量ai(i=1,2,…,m总能做到ai≡ai′(modk+1),即对方取a(1≤k),己方取k+1-a,使两人各取一次之后该分量减小k+1,也就对第i堆各取n(n≥1)次之后石子数便由ai=ai′+n(k+1)变成ai′,故在{a1′,a2′,…,am′;k}中有取胜策略的一方在{a1,a2,…,am;k}中也有取胜策略。

     

    游戏Ⅱ 有若干堆任意数目的小石子{a1,a2,…,am},两人轮流从中取石子,每人每次可以取走任意一堆中任意数目的石子,不能不取,把石子取完的人为胜者。

    采用m元数组{a1,a2,…,am}(m≥1)来描述这类取石子游戏,一人取走一次石子相当于用某个T变换把其中某个分量ai(1≤i≤m)减小为ai′,即{a1,a2,…,ai,…,am}T{a1,a2,…,ai′,…,am}(0≤ai′<ai)。

    有趣的是为了解决这类一般情况,我们需要用到整数的二进位制,把m元数组{a1,a2,…,am}中的每一个分量用二进位制数表示,ai(1≤i≤m)写在第i行,同时对齐二进位制数的位数,在列上作十进位制加法,其和写在第(m+1)行,记为{n1,n2,…,nj,…,nl},如果所有这些和数nj(1≤j≤l)均为偶数,我们称这个m元数组为偶数组;若nj(1≤j≤l),中有一个数为奇数,则称之为非偶数组。

    例如:对于3元数组{2,3,5};

    a1    2      0  1  0

    a2    3      0  1  1

    a3    5      1  0  1

    1    2  2

    n1  n2  n3

    因为其中n1=1,所以{2,3,5}是非偶数组。

    同样,对于3元数组{2,3,1}:

    a1    2    1  0

    a2    3    1  1

    a3    1    0  1

    由于nj(j=1,2)为偶数,则{2,3,1}为偶数组。

    偶数组与非偶数组在T变换下具有如下性质:

    (1)偶数组经过一次T变换之后一定变为非偶数组;

    (2)对于非偶数组,一定可以找到某一个T变换,使其变为偶数组。

    这样我们容易判定:如果给定的m元数组是偶数组,则后取者必有获胜策略;相反,若给定m元数组为非偶数组,则先取者有方法获胜,因为给定的m元数组为偶数组,先取者无论怎样取,只能将偶数组变为非偶数组,后取者则有策略将此时的非偶数组变为偶数组,由于每次取走石子,剩下石子数目一定越来越小,而{0,0,…,0}是偶数组,所以后取者获胜,同理可证相反情况。

    例2 有三堆石子,各堆数目分别是2、3、6,两人轮流取,取完的人为胜者,若甲先乙后,谁取胜?

    解:

    a1    2    0  1  0

    a2    3    0  1  1

    a3    6    1  1  0

               1  3  1

               n1 n2  n3

    ni为奇数i=1,2,3,所以{2,3,6}为非偶数,我们可以判定:先取者甲获胜,依性质证明过程给出的操作方法,只需将a3=6变为1,可以验证{2,3,1}是偶数组,无论乙如只可能变成如下六种情形之一:{2,3,0},1},{2,1,1},{2,0,1},{1,3,1},{0,3,1},都是非偶数组,同样按原方法可以将其变2}或{1,1},乙再取后,甲总能确保获胜。 

    例3: 12 届全国青少年信息学奥林匹克联赛初赛题现有5堆石子,石子数依次为3,5,7,19,50,甲乙两人轮流从任一堆中任取 (每次只能取自一堆,不能不取),取最后一颗石子的一方获胜。甲先取,问甲有没有获胜策略(即无论 乙怎样取,甲只要不失误,都能获胜)?如果有,甲第一步应该在哪一堆里取多少?请写出你的结果: _________________________________________________。

    解:由游戏Ⅱ知,得到如下推理:

    19    010011

    7   000111

    5        000101

    3        000011

              010010   (18)10

    50-18=32

    所以第1次只能在第5堆石子中取32粒,使得取出32粒后为偶数组。

    最后我们看一道综合利用游戏Ⅰ、Ⅱ的例子:

    例4 在3×25的棋盘上放着三颗石a、b、c(如图所示),两人轮流将石子向右移人一次只可以移动其中一颗石子1至5后无格可走者为输家,若甲先行,乙后行,赢?

    a

    b

    c

    解 由25≡7(mod6),根据游戏Ⅰ的策略{25,25,25;5}中有获胜策略的一方在{7,7,7;5}中也有获胜方法,又把石子由图中所示{3,2,6}移到{7,7,7}即相当于取石子游戏Ⅱ的{4,5,1},由于{4,5,1}是偶数组,故先移者输.

  • 相关阅读:
    CSS3中的Transition属性详解
    jq 全选/取消效果
    多维数组问题 int (*a)[] int []
    C语言输入多组问题~ungetc回退字符到stdin
    2015-12-14重启博客之旅
    转载~kxcfzyk:Linux C语言多线程库Pthread中条件变量的的正确用法逐步详解
    lsof 一切皆文件
    转载自~浮云比翼: 不忘初衷,照顾好自己。
    转载自~浮云比翼:Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)
    梳理回顾
  • 原文地址:https://www.cnblogs.com/rmy020718/p/9443240.html
Copyright © 2011-2022 走看看