博弈论

· · 个人记录

相关例题:nim游戏

Nim 游戏

题目

甲,乙两个人玩 nim 取石子游戏。

nim 游戏的规则是这样的:地上有 n 堆石子(每堆石子数量小于 10^4),每人每次可从任意一堆石子里取出任意多枚石子扔掉,可以取完,不能不取。每次只能从一堆里取。最后没石子可取的人就输了。假如甲是先手,且告诉你这 n 堆石子的数量,他想知道是否存在先手必胜的策略。

我们把这种游戏称为NIM博弈,游戏中面临的状态称为局面,第一个行动的称为先手,第二个行动的称为后手, NIM博弈不存在平局只存在先手必胜先手必败的两种情况。

\large{\mathbb{{\color {blue}A_1} {\color {red}\oplus}{\color{blue} A_2} {\color {red}\oplus}{\color {blue}A_3 }\cdots {\color {red}\oplus}{\color {blue} A_n} = 0}}

先手必败

\large{\mathbb{{\color {blue}A_1} {\color {red}\oplus}{\color{blue} A_2} {\color {red}\oplus}{\color {blue}A_3 }\cdots {\color {red}\oplus}{\color {blue} A_n} \ne 0}}

先手必胜

可得,我们只需把所有石头\mathbb{\large\color{red}\oplus}异或起来即可

那么如何证明正确性?

假设到最后一步,即所有石头都妹有了,我们不能进行任何操作

\large{\mathbb{{\color {blue}0} {\color {red}\oplus}{\color{blue} 0} {\color {red}\oplus}{\color {blue}0 }\cdots {\color {red}\oplus}{\color {blue} 0} =\color{orange} 0}}

另一种情况

\large \mathbb{{\color {blue}A_1} {\color {red}\oplus}{\color{blue} A_2} {\color {red}\oplus}{\color {blue}A_3 }\cdots {\color {red}\oplus}{\color {blue} A_n} ={ \color{orange}X}({\color{orange}X} \ne 0)}

假设\large \mathbb{\color {orange}X}的二进制最高的1位在第\large\mathbb\green{K}位,那么\large \mathbb {\color{blue} A_1 \sim A_k}位上一定存在\large \mathbb \color{blue}A_i它的第\large\mathbb\green{K}位为1 显然\large \mathbb{{\color {blue}A_i} {\color {red} \oplus} x_i <{\color{blue} A_i}}

由于我们可以拿走\large \mathbb{{\color {blue}A_i} - ({\color {blue}A_i} {\color {red}\oplus} {\color {orange}X})}使 {\large \mathbb\color {blue}A_i}变成\large \mathbb{}{{\color {blue}A_i}{{\color {red}\oplus} {\color {orange}X}}}

对于任何一个局面,若

\large{\mathbb{{\color {blue}A_1} {\color {red}\oplus}{\color{blue} A_2} {\color {red}\oplus}{\color {blue}A_3 }\cdots {\color {red}\oplus}{\color {blue} A_n} = 0}}

那么无论如何拿石头得到局面下石头异或和都不为0 我们可以用反证法:

\large{\mathbb{{\color {blue}A_1} {\color {red}\oplus}{\color{blue} A_i}{\color {red}\oplus}{\color{blue} A_2} {\color {red}\oplus}{\color {blue}A_3 }\cdots {\color {red}\oplus}{\color {blue} A_n} = 0}}

\large \mathbb \color {blue}{A_i \to A_i^`} \large{\mathbb{{\color {blue}A_1} {\color {red}\oplus}{\color{blue} A_i^`}{\color {red}\oplus}{\color{blue} A_2} {\color {red}\oplus}{\color {blue}A_3 }\cdots {\color {red}\oplus}{\color {blue} A_n} = 0}} \large{\mathbb{({\color {blue}A_1} {\color {red}\oplus}{\color{blue} A_i}{\color {red}\oplus}{\color{blue} A_2} {\color {red}\oplus}{\color {blue}A_3 }\cdots {\color {red}\oplus}{\color {blue} A_n} ) {\huge { \color {red}\oplus}} (\large{\mathbb{{\color {blue}A_1} {\color {red}\oplus}{\color{blue} A_i^`}{\color {red}\oplus}{\color{blue} A_2} {\color {red}\oplus}{\color {blue}A_3 }\cdots {\color {red}\oplus}{\color {blue} A_n}) }}}} \large \mathbb{ \color {red}A_i = A_i'}

与不能不取石头矛盾

证毕

代码如下

#include <iostream>

using namespace std;

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,res = 0;
        scanf("%d",&n);
        while(n--)
        {
            int x;
            scanf("%d",&x);
            res ^= x;

        }
        if(res)puts("Yes");
        else puts("No");
    }
    return 0;

}