【学习】Nim博弈

忽然发现博弈论是个很好玩的东西哎

之前假期学长讲课的时候就发现这种必胜的战略可以用来坑人做题

这两天终于做了第一道博弈论的题,写篇博客纪念一下

灵感来源:洛谷P1247

Pre-scene

众所周知,李明和Jenny都喜欢Danny,为了争夺Danny的所有权,他们决定玩一个游戏。规则是这样的:

有k堆扑克牌(不成套),两人轮流从某一堆中拿出x张牌,不能不拿,也不能跨堆拿牌,拿走最后一张(堆)牌的一方获胜。

命运当然是公平的,李明来向你请教有没有必胜的方法,你聪明的,能告诉他么


0X10  知识

先来了解一下,什么是Nim博弈


通常的Nim游戏的定义是这样的:有若干堆石子,每堆石子的数量都是有限的,合法的移动是“选择一堆石子并拿走若干颗(不能不拿)”,如果轮到某个人时所有的石子堆都已经被拿空了,则判负(因为他此刻没有任何合法的移动)。

                                                                                                                                ——百度百科 


了解Nim游戏之后,我们会发现这是一个经典的ICG游戏(不要问我什么是ICG因为我百度百科也不知道)

显然游戏有两种局面,先手必败和先手必胜,我们分别定义他们为P-position和N-position两种,其中P代表Previous,N代表Next,那么我们可以得出,从N-position转移而来的一定是P-position,反之也成立。

0X20  简单的证明

我们先来手玩一组小数据,一共有2堆石子,每一堆都有3个,你是先手的话,会怎么拿?由规则我们知道,玩家的目标是拿走最后一个石子,所以先手的你一定不会把某一堆全部拿走,因为如果这样,后手将会拿走另一堆,先手必败;但是如果你先拿1个,后手会跟着你从另一堆也拿一个,你拿2个,后手仍可以做和你一样的操作,先手必败。至此我们发现,(3,3)是一个P-position的局面。

推论:1.当a1^a2^a3^……a^n=0时,为P-position,即先手必败。

         2.当a1^a2^a3^……a^n!=0时,一定存在某个移动,使得局面变成一个P-position,即此局面为N-position。

0X30  实现

直接异或运算即可,代码过于简单就不放了。

0X40  题解

传送门

了解了上述知识后,这道题几乎就是一个裸的板子了,就是加了一个输出怎么取和取完的状态而已,这也很好实现。

0X41  怎么取

由于我们发现异或和不等于0,我们就要考虑怎么取使得其等于0了。

设k=a1^a2^a3^……a^n,因为k!=0,而显然k^k=0,所以要使a1^a2^a3^……a(n-1)^an^k=0,只需要把其中一个ai变成ai^k即可,又因必须要取,可得ai^k<ai

0X42  取完的状态

直接更改即可

0X43  代码

 1 //
 2 //  main.cpp
 3 //  Luogu
 4 //
 5 //  Created by gengyf on 2019/5/16.
 6 //  Copyright © 2019 yifan Geng. All rights reserved.
 7 //
 8 
 9 #include <cstdio>
10 int n;
11 int a[500005];
12 int main(){
13     scanf("%d",&n);
14     int check=0;
15     for(int i=1; i<=n; i++){
16         scanf("%d",&a[i]);
17         check^=a[i];
18     }
19     if(!check){
20         printf("lose
");
21         return 0;
22     }
23     for(int i=1; i<=n; i++){
24         if((check^a[i])<a[i]){
25             printf("%d %d
",a[i]-(check^a[i]),i);
26             for(int j=1; j<=n; j++)
27                 if(j!=i)
28                     printf("%d ",a[j]);
29                 else    printf("%d ",check^a[i]);
30             break;
31         }
32     }
33     return 0;
34 }
原文地址:https://www.cnblogs.com/gengyf/p/10878126.html