【编程之美】1.11 NIM(1) —— 排石头的游戏

题目大意如下:

N块石头排列成一行,每块石头对应一个编号。两个玩家依次取石头,每次取只能取任意一块或者相邻的两块。

石头在游戏过程中不能移位,最后将剩下的石头一次取光的玩家获胜。

问:该游戏是否存在必胜策略。

拓展问题:

1. 若最后取光石头的人输,又该如何应对?

2. 两人轮流取,每次最少取一块,最多取K块,最后取走石头的人赢得游戏。如何应对?

———-一些想法——————–

对于原问题

注意取石头的规则,只能取一块或相邻两块。

假设玩家分别为A和B 先从A开始取。

分析一些特例:

N = 1 A肯定能赢。

N = 2 A肯定能赢。

N = 3 A取走中间位置的石头 那么剩下的B只能先取走一块,最后一块A取走。  所以还是A赢。

N = 4 A取走中间位置的两颗 剩下的与N = 3类似 还是A赢。

从以上的一些特例可以得出:

无论N 为奇数还是偶数,A先从最中间的位置取石头(一块or相邻两块) 

剩下的两部分 B取哪个位置 A就取另一部分对称位置的石子。

这样 A也可以赢。

所以 按照上述策略 总可以保证第一个取石子的玩家赢得游戏。

对于扩展问题1

还是举例子分析:

N = 1 A肯定输了。

N = 2 A赢。

N = 3 A赢。

N = 4 A肯定输了。

~A取一块 B就取两块 剩下的一块必定是A取到 A输  

~A取两块 B就取一块 剩下的一块必定是A取到 A输

N = 5 A取一块 问题转换为 N = 4的情形 因此 A赢。

N = 6 A取最前两块 问题转换为 N = 4的情形 因此 A赢。

找规律:大致推测 N = 3*n + 1时 A输。其余情况 A赢。

【暂时认为上面推测是正确的】

下面分析一下:

A取完一块 or 两块后可能出现的情形有以下几种:

【这时候轮到后手取石子】

① 剩下的石子是一部分 若这部分是必输的状态,则先手赢。

② 剩下的石子是两部分

     一、 两部分都是必赢态 此时A肯定输了。

     二、两部分都是必赢态  双方玩家都希望自己能第一部分输,而不是赢。

             因此这时候是无法判断的。

     三、一部分是必赢态 一部分是必输态

             若后手先取必输态内的石子 先手赢。

             若后手先取必赢态内的石子 这时候是无法判断的。

            【因为都希望自己在必赢态中失败 以让对方先取必输态内的石子】

因此似乎不存在必赢态,在N > 6时 是需要双方进行博弈的。

举个例子证明 N = 3 * n + 1不是必输态。

N = 7 {1 2 3 4 5 6 7}

A先取4  剩下两部分 {1 2 3}  {5  6 7}

接下来B可以选择:

—— B取一块石子

           ① B取边缘的石子{1}  => {2 3} {5 6 7}

                  A取{7} => {2 3} {5 6}

                      B取一块 比如{2} => {2} {5 6}

                             A取{5 6} 剩下的是B取到。

                      B取两块 比如{2 3}  => {5 6}

                             A取{5}  剩下的还是B取到。

                   因此 A赢。

             ② B取中间的石子{2}  => {1 3} {5 6 7}

                     A取{5 6} => {1 3} {7}   

                     剩下的石子都是单独的  一次只能取一块  最终A赢。

—— B取两块石子

              B取{1 2}  => {3} {5 6 7}

                 A取{6}  => {3} {5 7}  最终A赢。

这是一个反例  说明 并不是 N = 3*n + 1 是必输态。

另一些思路:

参考网络的资料  给出了N = 7时 必赢的策略。

在此感谢~

详见:Aleee ——NIM(1)一排石头的游戏之扩展问题解法

作者利用程序写出了递归求解思路,并给出了C#的算法。

算法复杂度是一个问题 求解时间很长。

下面给出 N = 7时 必赢策略。

A取第2块石子。         =>          {1} {3 4 5 6 7}

首先定义几种必输态。

LOSE1 —— {1 1 1} 先必比输

LOSE2 —— {2 2} 先手必输

LOSE3 —— {4} 先手必输

{4} 先手必输 

接下来 遍历 B取石子的所有可能性。

 ① B取{1}  A{3}       ==> LOSE3

 ② B{3} A{1}            ==> LOSE3

 ③ B取{4} A{5 6}     ==> LOSE1

 ④ B取{5} A{1}        ==> LOSE2

 ⑤ B取{6} A{3 4}     ==> LOSE1

 ⑥ B取{7}  A{1}        ==> LOSE3

 ⑦ B取{3 4}   A{6}    ==> LOSE1

 ⑧ B取{4 5}   A{6}     ==> LOSE1

 ⑨ B取{5 6}   A{3}     ==> LOSE1

 ⑩ B取{6 7}   A{4}     ==> LOSE1

对于扩展问题2

这里每个玩家每次可以取1 ~ K块石子。

① K >= N时 A必赢

② K < N时 每一轮保证两个玩家总共取的石子数为【K + 1】

为什么是K + 1 ? 这个数是我们从必赢的角度看要满足的条件。

玩家A取了X块石子 B可以选(K + 1-X)块石子 这一轮完成。

X = 1 那么B可以取K个。

X = K 那么B可以取1个。

如果不是K + 1   

比如是 K  那么玩家A取K个        玩家B至少取一个 一轮总数大于K  那么必然无法满足必赢策略。

比如是 K + 2  那么玩家A取1个  玩家B最多取K个  一轮总数小于 K + 2  那么必然也无法满足必赢策略。

同理 对于 任意小于(K + 1) 和大于 (K + 1)的数 必赢策略都无法满足。

令 N = a * (K + 1) + b 

【a肯定会≥1    <=======  N > K 那么至少 N = K + 1】

如果 b = 0 说明玩家可以进行a轮取石子游戏。  那么这时候B必赢

如果 b != 0  那么先手玩家先取b-1块石子

之后B取X块石子 那么下一轮A就取(K +1 – X)块石子 

这样可以保证最后一轮 轮到A取到最后一块石子。  A必赢

综上:

N % (K + 1) = 0时 B必赢。

其余情况 A必赢。

因此 K 很大 N随机的情况下  先手获胜的概率很大~

    原文作者:果岭里29
    原文地址: https://blog.csdn.net/u013575812/article/details/50970796
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞