百度百科

Definition

这样的游戏被称为Nim游戏:

1、有两个玩家,轮流进行操作

2、是公平游戏。即面对同一局面两个玩家所能进行的操作是相同的。例如中国象棋不是公平游戏。因为面对同一个局面,红方只能移动红色棋子而不能移动黑方棋子,黑房同理。

3、一个玩家是输掉当且仅当他无法进行操作。例如如果是两个人轮流取石子的游戏,那么一个玩家输掉当且仅当他面前没有石子了。因为他下面无法进行取石子的操作。

一般的,Nim游戏指两个玩家轮流在好几堆东西中取物品,不能夸堆取,无法操作判负。

Solution

对于Nim游戏的解法,因为状态显然是不可逆的,所以可以对状态的转移图进行拓扑排序然后DP求解。但是对于大部分博弈题目,状态多的难以计算,所以需要考虑更简单的方法。

结论:一个Nim游戏中的状态是必败状态当且仅当每个子游戏的异或和为0.

这里子游戏代表构成Nim游戏中最基础的游戏。例如两个人轮流取三堆石子的游戏是三个取一堆石子的游戏组合而成的。对于每个子游戏显然可以用一个正整数代表当前的状态,即还剩多少石子。Nim游戏的子游戏状态异或和为\(0\),则必败。

证明:我有一个绝妙的想法,可惜这里写不开

对于一个异或和不为\(0\)的状态,那么他是必胜态。

考虑在一个必胜态下如何进行下一步。

设异或和是\(X\)。设\(X\)二进制的最高为1位是第\(k\)位。

那么显然存在至少一个状态使得他们二进制第\(k\)位为1。否则第k位异或和应该是0。

那么就任选一个第k位是1的状态,设他的状态是\(Y\),那么将他可以将\(Y\)这一堆取成\(Z=X~xor~Y\)那么得到的状态是必败状态。

证明如下:

首先,\(Y\)可以取成\(Z\)当且仅当\(Z~\leq~Y\)。首先证明\(Z~\leq~Y\)。

因为\(Y\)和\(X\)第\(k\)位都是\(1\),更高位都是\(0\)。那么异或后\(Z\)第\(k\)位一定是\(0\),更高位显然是\(0\)。所以\(Z\)的位数比\(Y\)的位数要少。那么显然\(Z~\leq~Y\)。

下面证明更改后的状态是必败状态

根据\(Z=X~xor~Y\),并且\(A~xor~A=~0~\)。可得:

更改后的状态

\(S~=~X~xor~Y~xor~Z~=~X~xor~Y~xor~(~X~xor~Y~)\)

\(=~(~X~xor~Y~)~xor~(~X~xor~Y~)~=~0~\)

一定是一个必败状态。

Example

传送门

Description

输入k及k个整数n1,n2,…,nk,表示有k堆火柴棒,第i堆火柴棒的根数为ni;接着便是你和计算机取火柴棒的对弈游戏。取的规则如下:每次可以从一堆中取走若干根火柴,也可以一堆全部取走,但不允许跨堆取,也不允许不取。

Input

第一行,一个正整数k

第二行,k个整数n1,n2,…,nk

Output

如果是先取必胜,请在第一行输出两个整数a,b,表示第一次从第b堆取出a个。第二行为第一次取火柴后的状态。如果有多种答案,则输出<b,a>字典序最小的答案(即b最小的前提下a最小)。

如果是先取必败,则输出“lose”。

Sample Input_1

3
3 6 9

Sample Output_1

4 3
3 6 5

Sample Input_2

4
15 22 19 10

Sample Output_2

lose

Hint

\(k~\leq~500000\)

\(n_i~\leq~1e9\)

Solution

板子题要啥solution

Code

#define rg register
#define ci const int
#define cl const long long int typedef long long int ll; namespace IO {
char buf[90];
} template<typename T>
inline void qr(T &x) {
char ch=getchar(),lst=' ';
while(ch>'9'||ch<'0') lst=ch,ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
if(lst=='-') x=-x;
} template<typename T>
inline void write(T x,const char aft,const bool pt) {
if(x<0) x=-x,putchar('-');
int top=0;
do {
IO::buf[++top]=x%10+'0';
x/=10;
} while(x);
while(top) putchar(IO::buf[top--]);
if(pt) putchar(aft);
} template<typename T>
inline T mmax(const T a,const T b) {if(a>b) return a;return b;}
template<typename T>
inline T mmin(const T a,const T b) {if(a<b) return a;return b;}
template<typename T>
inline T mabs(const T a) {if(a<0) return -a;return a;} template<typename T>
inline void mswap(T &a,T &b) {
T temp=a;a=b;b=temp;
} const int maxn = 500010; int n,ans;
int MU[maxn]; int main() {
qr(n);
for(rg int i=1;i<=n;++i) {
qr(MU[i]);ans^=MU[i];
}
if(!ans) {
puts("lose");return 0;
}
int _temp=1<<30;
while(!( _temp & ans )) _temp>>=1;
for(rg int i=1;i<=n;++i) if(MU[i] & _temp){
int z=ans^MU[i];
write(MU[i]-z,' ',true);write(i,'\n',true);
for(rg int j=1;j<=n;++j) {
if(j != i) write(MU[j],' ',true);
else write(z,' ',true);
}
break;
}
return 0;
}

Summary

Nim游戏是必败态当且仅当子游戏状态异或和为0。否则是必胜态。通过必胜态一定可以通过一步操作变成必败状态。

【博弈论】Nim游戏的更多相关文章

  1. 博弈论之Nim游戏

    Nim游戏是组合游戏(Combinatorial Games)的一种,属于“Impartial Combinatorial Games”(以下简称ICG). 通常的Nim游戏的定义是这样的:有若干堆石 ...

  2. 博弈论入门之nim游戏

    更好的阅读体验点这里 nim游戏 nim游戏 有两个顶尖聪明的人在玩游戏,游戏规则是这样的: 有\(n\)堆石子,两个人可以从任意一堆石子中拿任意多个石子(不能不拿),没法拿的人失败.问谁会胜利 ni ...

  3. 【博弈论】浅谈泛Nim游戏

    Nim游戏在ACM中碰到了,就拎出来写写. 一般Nim游戏:有n堆石子,每堆石子有$a_i$个,每次可以取每堆石子中$[0,a_i-1]$,问先手是否有必胜策略. 泛Nim游戏:每堆石子有$a_i$个 ...

  4. [您有新的未分配科技点]博弈论入门:被博弈论支配的恐惧(Nim游戏,SG函数)

    今天初步学习了一下博弈论……感觉真的是好精妙啊……希望这篇博客可以帮助到和我一样刚学习博弈论的同学们. 博弈论,又被称为对策论,被用于考虑游戏中个体的预测行为和实际行为,并研究他们的应用策略.(其实这 ...

  5. Nim游戏与SG函数 ——博弈论小结

    写这篇博客之前,花了许久时间来搞这个SG函数,倒是各路大神的论文看的多,却到底没几个看懂的.还好网上一些大牛博客还是性价比相当高的,多少理解了些,也自己通过做一些题加深了下了解. 既然是博弈,经典的N ...

  6. BZOJ_3105_[cqoi2013]新Nim游戏_线性基+博弈论

    BZOJ_3105_[cqoi2013]新Nim游戏_线性基+博弈论 Description 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作 ...

  7. (博弈论)51NOD 1069 Nim游戏

    有N堆石子.A B两个人轮流拿,A先拿.每次只能从一堆中取若干个,可将一堆全取走,但不可不取,拿到最后1颗石子的人获胜.假设A B都非常聪明,拿石子的过程中不会出现失误.给出N及每堆石子的数量,问最后 ...

  8. 洛谷$P$4301 $[CQOI2013]$新$Nim$游戏 线性基+博弈论

    正解:线性基 解题报告: 传送门! 这题其实就是个博弈论+线性基,,,而且博弈论还是最最基础的那个结论,然后线性基也是最最基础的那个板子$QwQ$ 首先做这题的话需要一点点儿博弈论的小技能,,,这题的 ...

  9. 博弈论入门——Nim游戏引入

    说实话,我真的对这个游戏看得是一脸懵逼,因为(我太弱了)我没有明白一些变量的意思,所以一直很懵,现在才明白,这让我明白博弈论(还可以骗钱)博大精深; 以下是我自己思考的过程,也许不严谨,但是最终明白了 ...

  10. 博弈论(nim游戏,SG函数)

    说到自己,就是个笑话.思考问题从不清晰,sg函数的问题证明方法就在眼前可却要弃掉.不过自己理解的也并不透彻,做题也不太行.耳边时不时会想起alf的:"行不行!" 基本的小概念 这里 ...

随机推荐

  1. Selenium 入门到精通系列:二

    Selenium 入门到精通系列 PS:用户登录 例子 #!/usr/bin/env python # -*- coding: utf-8 -*- # @Date : 2019-04-23 16:12 ...

  2. python一标准异常总结大全(非常全)

    Python标准异常总结 AssertionError 断言语句(assert)失败 AttributeError 尝试访问未知的对象属性 EOFError 用户输入文件末尾标志EOF(Ctrl+d) ...

  3. Unity编辑器 - 资源修改立即写入磁盘AssetDataBase.SaveAssets()

    Unity编辑器 - 资源修改立即写入磁盘AssetDataBase.SaveAssets() 在编写编辑器时,如果需要修改Unity序列化资源(如Prefab,美术资源,ScriptableObje ...

  4. 211. String Permutation【LintCode by java】

    Description Given two strings, write a method to decide if one is a permutation of the other. Exampl ...

  5. hdu刷题2

    hdu1021 给n,看费波纳列数能否被3整除 算是找规律吧,以后碰到这种题就打打表找找规律吧 #include <stdio.h> int main(void) { int n; whi ...

  6. The Activation Function in Deep Learning 浅谈深度学习中的激活函数

    原文地址:http://www.cnblogs.com/rgvb178/p/6055213.html 版权声明:本文为博主原创文章,未经博主允许不得转载. 激活函数的作用 首先,激活函数不是真的要去激 ...

  7. jQuery实现仿京东商城图片放大镜

    效果图: 不废话直接上代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...

  8. JS中通过数组的方式操作字符串 数组是个好东西 ....

    题目:使用JS将 var str="what are you nong sha lei",通过您的方法转换为"What Are You Nong Sha Lei" ...

  9. 图的遍历——DFS(邻接矩阵)

    递归 + 标记 一个连通图只要DFS一次,即可打印所有的点. #include <iostream> #include <cstdio> #include <cstdli ...

  10. Khan Academy

    Khan Academy是一个免费的学院. 致力于教育改革. 百度百科:ohn Resig 百度百科有记者采访,采访内容比较有意思.