博弈论入门
博弈论(Game Theory)
首先先说两个定义
N状态:前面的一个玩家必胜
P状态: 后面一个玩家必胜
巴什博弈 (Bush Game)
有一堆数量为n的物体,轮流拿,至少拿1个,至多拿k个(N>K);
如果n%(k+1)==0
,那么先手必败。这一切是显而易见,毫无疑问的
一道例题
Tang and Jiang are good friends. To decide whose treat it is for dinner, they are playing a game. Specifically, Tang and Jiang will alternatively write numbers (integers) on a white board. Tang writes first, then Jiang, then again Tang, etc… Moreover, assuming that the number written in the previous round is X, the next person who plays should write a number Y such that 1 <= Y - X <= k. The person who writes a number no smaller than N first will lose the game. Note that in the first round, Tang can write a number only within range [1, k] (both inclusive). You can assume that Tang and Jiang will always be playing optimally, as they are both very smart students.
这一道题目大意上和Bush Game 差不多,但是不同的是它里面说的是写不出不小于n的就输了,那么必胜的时候就是你已经写出了n-1的时候。所以此时如果(n-1)%(k+1)==0
那么先手必定输,否则就是后手输,因为先手那一次后可已转换为第一种情况
尼姆博弈 (Nim Game)
有n堆物体,每一堆的数量为a[i]个,每一次一个人任选一堆取出任意个(不能为0)
设k为每一堆异或的结果,如果k==0
,那么先手必定失败,否则先手必定胜利。
这样来想,把每一堆的数量转换成二进制然后竖着来最低位对齐。如果说k==0
,那么这意味这每一个列的1的个数一定会是偶数个。而第一个人取走了一些以后呢,这意味着一定一些列的1的个数为变成奇数个,那么k一定就不再等于0了。而此时后手的人只要把异或的值修正为0就可以了。
因为k不等于0了,那么这就说明k的最高位一定会是1,而这个最高位的1一定会是a[i]中的对应位上的1提供的。
而根据异或的性质,k和a[i]异或结果为其他的异或结果。
我们可以在a[i]中减去一些值,是a[i]最终等于k和a[i]异或的结果,又因为k最高位的1是由a[i]提供的,那么那里一定会变成0,就一定会比a[i]小,而只要把这里减掉,k就又会等于0了
SG函数
公平组合游戏
1.双方交替来进行;
2.游戏进行的任意时刻,可以执行的合法行动与哪一个玩家执行无关;
3.当玩家无法行动的时候,就判负
mex运算
$$
mex(S)=min{x|x\in N,x\notin S}
$$
SG函数
对于任意状态下的x
$$
SG(x)=mex{SG(y)|y是x的后继状态}
$$
对于终止状态,SG值为0。
如果某一状态后继SG有0,则当前状态为N
如果当前状态所有后继SG不为0,则当前为P;
好的,既然已经知道了SG函数是什么,那么就有一道题了。
移棋子游戏
Description
给定一个有N个节点的DAG图,图上某些节点上面有棋子。两名玩家交替移动棋子,玩家每一次可以将任意一颗棋子沿着有向边移动到下一个节点,当无法移动的时候,就输掉了游戏,假设双方都足够聪明,问先手必胜还是后手必胜。
Input
第一行三个整数N,M,K,表示N个节点M条边K个棋子。接下来M行,每行两个整数x,y,代表x节点到y节点的有向边再接下来K行,表示K个棋子所在的节点编号。
output
先手胜输出”win”,否则输出”lose”
Sample Input
1 | 6 8 4 |
Sample Output
1 | win |
这应该是我第一次这么抄题吧。
DAG图,看到这个应该回想起拓扑排序,其次,因为没有后继的点$SG$值为0,而每一个点的$SG$值又是有它的后继决定的。如果它的后继没有弄完,那么就不可以算。这很像拓扑排序把入度为0的点push进队列。
因此不难想到这一题可以用类似于拓扑排序的方法来做。我们需要存两个图,正向的和反向的。正向的图用来寻找这一个点的后继获取这一个点的$SG$值,反向的用来找祖宗,修改祖宗的出度,并把出度为0的祖宗push进入队列
因为有拓扑排序的基础,所以这一道题可以比较容易的做出来了
1 |
|
那么,That’s all.