文章目录

  • 前言
  • 巴什博弈
  • 威佐夫博弈
  • Nim游戏
  • Nim游戏与sg函数
    • 题目
    • 题意
    • 样例
    • 思路
    • 代码

前言

从今天开始复习和整理下acm的部分模块,从博弈论开始。
著名的“取石子”游戏通常有3种类型,从简单到复杂依次是:
1.巴什博弈
2.威佐夫博弈
3.Nim游戏
4.Nim游戏与sg函数
复习Nim博弈之前,先复习下前两者。


巴什博弈

大意:

一堆物品有n个,两个人轮流从这堆物品中取物,规定每次至少取一个,最多取m个。最后取光者得胜,问最优策略下谁赢。

思路:

不难发现,当剩下m+1个物品时,先手必败。

所以,如果当前的物品个数是(m+1)的倍数,无论先手如何取,后手都总能把剩下的物品数变成(m+1)的倍数 ,后手必胜。 反之,如果当前的物品个数不是(m+1)的倍数,那么先手总能将剩下的物品个数变成(m+1)的倍数,先手必胜。

结论:

当 n % (m+1) ==0 时 ,后手必胜;反之,先手必胜。


威佐夫博弈

大意:

有两堆石子,数量任意,可以不同。游戏开始由两个人轮流取石子。游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子;二是可以在两堆中同时取走相同数量的石子。最后把石子全部取完者为胜者。现在给出初始的两堆石子的数目,你先取,假设双方都采取最好的策略,问最后你是胜者还是败者。

题目:
洛谷P2252
https://www.luogu.com.cn/problem/P2252

思路:
同上,找出必败态,根据必败态寻找规律,不再赘述。

结论:
设两堆石头分别有a,b个,其差值为d。

其必败态为: d *[ (sqrt(5) +1) / 2 ] == min(a,b) .

其中(sqrt(5) +1) / 2 是黄金分割(好神奇)。


Nim游戏

大意:
有n堆石子,第i堆石子有ai个。每次可以从一堆石子中取任意多个,取到最后一颗石子的人获胜,问最优策略下谁赢。

思路:
网上太多了,就不再赘述了。采用二进制进行异或的方法是真的很妙。。。

结论:
sum = a1^ a2 ^a3 ^a4 ^ … … ^an ; ( ^ 即异或)
sum == 0 ,后手胜;
sum == 1 ,先手胜;


Nim游戏与sg函数

虽然Nim游戏可以采用直接求异或和的方法获得答案,但我们很容易发现,Nim游戏其实只是这一类组合游戏中的一种极特殊的情况。倘若我们对Nim游戏中的取石子规则稍作修改,例如:
只能取斐波那契数;
只能取质数;
只能取某些指定的数字;
这时就必须引入sg函数进行处理。

sg函数即对于当前的局面i:
sg[i] = mex{可以由当前局面转移到的每一个局面的sg值}
其中mex{} 运算是取最小的不属于该集合的自然数
例如,
最终态是局面0,则sg[0] = 0。

由局面1可以且仅可以转移到局面0,
则sg[1] = mex{sg[0]} = mex{0} = 1;

由局面2可以且仅可以转移到局面0,1,
则sg[2] = mex{sg[0],sg[1]} = mex{0,1} = 2;

由局面3可以且仅可以转移到局面0,2,
则sg[3] = mex{sg[0],sg[2]} = mex{0,2} = 1;

sg函数为Nim游戏提供了一个很好的解题模型,那就是:
把原游戏分解成多个独立的子游戏,
则原游戏的SG函数值是它的所有子游戏的SG函数值的异或。

来看下面这道例题:

题目

题意

还是Alice和Bob的游戏,
给一个仅由大写英文字母构成的字符串(length<=40) ,
每一次可以删去相同的一个,两个或者全部的字母。
删掉最后一个字母的人将获胜,问最优策略下谁赢?

样例

思路

显然,我们把相同的字母放在一个堆中,这就是Nim游戏的一个简单变形。
仅仅把 “从一个堆中任意取出石子 ” 变成 “从一个堆中取出1,2 或 全部 石子”。

我们需要一个sg[i][j] 来记录第i堆石子在剩下j枚石子时的sg值。
其中 sg[i][j] = mex{ sg[i][0],sg[i][j-2],sg[i][j-1]} ,采用递推实现。
最后将每一堆的sg[i][size] 求异或和就好了。具体见代码。

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn = 50;
int box[maxn];
int sg[maxn][maxn];  //sg[i][j] 第i堆石子剩下j枚石子时的sg值
vector<int> v;     //存放每堆石子的个数
char s[maxn];      void get_sg(){int size = v.size();for(int i=0;i<size;i++){sg[i][0] = 0;sg[i][1] = 1;for(int j=2;j<=v[i];j++){int f[3] = {sg[i][0],sg[i][j-1],sg[i][j-2]};  //对于当前sg[i][j]可以转移到的3种状态,-1,-2和清空。for(int k=1;k<=3;k++){     //由题意可知,sg[i][j]只可能在0,1,2,3中取值 if(k!=f[1]&&k!=f[2]){sg[i][j] = k;break;}}}}
}
int main(){cin>>s;int len = strlen(s);for(int i=0;i<len;i++){int now = s[i] - 'A';box[now]++;}for(int i=0;i<maxn;i++){if(box[i]!=0)v.push_back(box[i]);}get_sg();int ans = 0;int size = v.size();for(int i=0;i<size;i++){ans ^= sg[i][v[i]];} if(ans) cout<<"Alice"<<endl;else cout<<"Bob"<<endl;return 0;
}

【acm 博弈论 】 之 Nim游戏与sg函数相关推荐

  1. 博弈论——关于Nim游戏和SG函数的几个链接

    今天做了一道博弈论的题目,正好去找找相关资料再复习一下. 网上能找到的都是同样的文章,不过我觉得足够了,Nim游戏百度百科里说的很详细,包括公式.证明之类的 http://baike.baidu.co ...

  2. Nim游戏和SG函数

    个人感觉这篇文章对Nim游戏和SG函数讲的非常清楚:点击打开链接 (放原文链接应该没关系吧QAQ)

  3. Nim 游戏和 SG 函数

    Nim游戏 Nim游戏定义 Nim游戏是组合游戏(Combinatorial Games)的一种,准确来说,属于"Impartial Combinatorial Games"(以下 ...

  4. [博弈论] Nim游戏及SG函数(经典+台阶+集合+拆分)

    文章目录 0. 前言 1. Nim 游戏+模板题 2. 台阶 - Nim 游戏+变种题 3. Mex运算与SG函数 4. 集合 - Nim 游戏+变种题 5. 拆分 - Nim 游戏+变种题 0. 前 ...

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

    普通Nim游戏: 有若干堆石子,两人轮流从中取石子,取走最后一个石子的人为胜利者 我们判断先手必胜还是先手必败就要判断先手面对的局面是必胜态还是必败态 并且普通Nim游戏满足以下性质: 1.无法移动的 ...

  6. 【学习笔记】NIM游戏与SG函数初探

    公平组合游戏ICG 游戏条件介绍: 由两名玩家交替行动 游戏进程的任意时刻,可以执行的合法行动与轮到的玩家无关 若当前玩家无法行动,则判负 则称该组合游戏为公平组合游戏.如NIM游戏等即是经典的公平组 ...

  7. Nim游戏入门+SG函数

    对于经典的Nim游戏,只需要把每一堆初始状态都异或起来,最后得到的结果非0的为必胜状态,结果为0的为必败状态. 原理:异或的结果非0的状态总能通过一次取物品操作,将此状态转化为结果为0的状态:而异或结 ...

  8. AcWing 893. 集合-Nim游戏(SG函数)

    题目链接 https://www.acwing.com/problem/content/895/ 思路 因为博弈的过程是一个状态交替的过程,而SG函数就是记录每一个状态交替的过程,从终点的必败态往前推 ...

  9. 组合游戏(Nim游戏)——SG函数

    SG为0的点(必败点)能到达的肯定都是SG不为0的点(必胜点): SG不为0的点(必胜点)一定能通过某种方式到达SG为0的点(必败点). 组合游戏典型例题: 给定n堆石子以及一个由k个不同正整数构成的 ...

最新文章

  1. Win7开机密码破解
  2. 解决Lync Server 2013无法共享演示PPT
  3. (gnome-ssh-askpass:609): Gtk-WARNING **: cannot open display:
  4. 算法笔记_218:花朵数(Java)
  5. raid5通常需要几块盘_raid5需要几块硬盘
  6. 里加一列为1_一素一菩提 @ 素牛排薯泥amp;百香龙珠气泡饮
  7. 菜鸟学C语言(五)之求定积分
  8. CodeForces - 456D A Lot of Games(字典树+博弈)
  9. 1、如何理解SQL Server的实例
  10. 牛客寒假算法基础集训营2 A处女座的签到题
  11. ajax怎么在服务器返回值,node.js+Ajax实现获取HTTP服务器返回数据?
  12. 树莓派做服务器装什么系统安装,树莓派 安装 群晖系统安装教程
  13. 同学聚会幽默 , 小学生搞笑图片
  14. SW中如何将拉伸的物体转化为钣金件
  15. JavaScript系列---for循环(打印星星)
  16. 员工主动提出加班,公司要支付加班费吗?
  17. 音频-基于Core Audio技术采集音频(版本2)
  18. 台式计算机风扇为什么光散热,电脑噪音太大了,要如何降噪?其实不光是风扇的事!...
  19. nand flash基础(一)
  20. DP 转 HDMI视频信号转换 CS5263替代IT6563

热门文章

  1. 用python更换桌面壁纸
  2. Win7 如何修改hosts文件
  3. reRender属性的使用
  4. 戴尔硬件服务器参数,戴尔_PowerEdge R540_机架式服务器参数_服务器推荐购买 | Dell 中国大陆...
  5. linux 拍照软件有哪些,六款基于Linux的开源照片管理软件推荐
  6. 服务器挂微信显示登陆异常怎么办,王者荣耀微信大区登录异常怎么办 王者荣耀微信提示网络繁忙/登录失败如何解决...
  7. 2022天梯L1-L2题解
  8. 苹果屏幕录制怎么没有声音_怎么录制屏幕?有哪些好用的录制屏幕软件
  9. spring boot runner,destory监听
  10. 三分钟集成 TapTap 防沉迷 SDK(Unity 版)