SG函数和SG定理的运用

SG函数和SG定理常用于解决博弈论的相关问题。其中SG函数的求解主要根据MEX运算。什么是MEX运算?MEX( minimal excludant ) 字面上意思是最小除外的那个数。 MEX是对一个集合的运算。指得是对于一个集合 s={a1,a2,an) 集合中未出现的最小非负整数。
举个例子:比如 s={1,2,3} 则MEX(s)=0, 如果s={0,1,2,4},则MEX(s)=3.
SG定理:博弈论中游戏和的SG值等于各个游戏的SG值的Nim和。Nim和也就是我们所说的按位异或运算下面上例题。

1.Fibonacci again and again

题目传送门:HDU1848
详细解释见下面代码。

#include<bits/stdc++.h>
using namespace std;
const int N=1e3+5;
#define mst(a) memset(a,0,sizeof s)
int f[16],sg[N],s[N],m,n,p; //f[i]储存改变状态的所有方式  sg[i]储存每个状态的sg值  ,s[i]保存后继状态所有sg值
void solve(){for(int i=1;i<=N;i++) //遍历 {mst(s);//每次都要对保存后继状态的集合s清空 for(int j=1;j<=16&&f[j]<=i;j++)//对所有满足条件的后继状态的sg值放入到集合s中 s[sg[i-f[j]]]=1;for(int k=0;;k++)if(!s[k])  //进行mex运算找到最小未出现的非负整数 即为sg值 {sg[i]=k;break;}    }
}
int main(){f[1]=1,f[2]=2;for(int i=3;i<=16;i++)//fibnacci递推 f[i]=f[i-1]+f[i-2];solve();while(cin>>m>>n>>p){if(!m&&!n&&!p) break;puts((sg[m]^sg[n]^sg[p])?"Fibo":"Nacci");//Nim和运算 若非0先手胜,反之后手胜。 }return 0;
}

2.巴什博弈的SG解法

如果对于不知道巴什博弈结论的人可以用SG函数直接求解
不过时间复杂度变成了O(nm)数据太大就只能记结论了。

#include<bits/stdc++.h>
using namespace std;
const int N=1e3+5;
int sg[N],s[N];
#define mst(a) memset(a,0,sizeof a)
void solve(int n,int m){  //时间复杂度O(nm) for(int i=1;i<=n;i++){mst(s);for(int j=1;j<=i&&j<=m;j++)s[sg[i-j]]=1;for(int k=0;;k++)if(!s[k]){sg[i]=k;break;}}
}
int main(){int t,n,m;cin>>t;while(t--){cin>>n>>m;solve(n,m);puts(sg[n]?"first":"second");}return 0;
}

3.尼姆博弈的SG解法

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+5;
int sg[N],s[N],n,a[N];
void sovle(){for(int i=1;i<N;i++){memset(s,0,sizeof s);for(int j=1;j<=i;j++)s[sg[i-j]]=1;for(int k=0;;k++)if(!s[k]){sg[i]=k;break;}}
}
int main(){int t;cin>>t;while(t--){cin>>n;int ans=0;for(int i=1;i<=n;i++)cin>>a[i],ans^=a[i];puts(ans?"Yes":"No");}return 0;
}

4.Roy&October之取石子II

题目传送门:P4860
由题目数据我们可知数据很大,显然用SG是不可能的。但是如果我们没找到规律 ,就可以用SG函数进行打表,通过打表发现的规律的可能性更大。下面给个打表代码。

#include<bits/stdc++.h>
using namespace std;
const int N=5e4+5,M=1e5+5;
int p[M],cnt=1,a[N];
void ss(int n){  //欧拉筛 for(int i=2;i<=n;i++)a[i]=1;for(int i=2;i<=n;i++){if(a[i]) p[cnt++]=i;for(int j=1;j<cnt&&p[j]*i<=n;j++){a[i*p[j]]=0;//最小质因数筛合数。 if(i%p[j]==0) break;}}
}
int sg[N],s[N];
void solve(){ //求sg函数 p[0]=1;for(int i=1;i<N;i++){memset(s,0,sizeof s);for(int j=0;p[j]<=i&&j<cnt;j++)s[sg[i-p[j]]]=1;for(int k=0;;k++)if(!s[k]){sg[i]=k;break;}}
}
int main(){ios::sync_with_stdio(false),cin.tie(0);ss(N);solve();for(int i=1;i<=100;i++)if(sg[i]) printf("%d:1\n",i);else printf("%d:0\n",i);return 0;
}


从表中我们知道凡是4的倍数都是后手胜。因此我们可以猜想只要n是4的倍数后手胜,否则先手胜。下面上正解代码

事实上,我们自己找规律也能找出来,比如n=1,2,3显然都是先手胜,n=4时,显然先手只能拿1或2或3个,所以n=4为必败态,n=5,6,7时先手都可以通过拿若干个棋子使对手面临n=4这个必败态,所以n=5,6,7为必胜态。
n=8时,先手只能拿1,2,3,5,7 显然后手胜,所以n=8为必败态,依次类推,规律显然。

#include<bits/stdc++.h>
using namespace std;
int main(){int t,n;cin>>t;while(t--){cin>>n;puts(n%4?"October wins!":"Roy wins!");}return 0;
}

SG函数和SG定理的运用相关推荐

  1. SG函数和SG定理(Sprague_Grundy)

    一.必胜点和必败点的概念 P点:必败点,换而言之,就是谁处于此位置,则在双方操作正确的情况下必败.        N点:必胜点,处于此情况下,双方操作均正确的情况下必胜. 必胜点和必败点的性质:    ...

  2. (转载)--SG函数和SG定理【详解】

    在介绍SG函数和SG定理之前我们先介绍介绍必胜点与必败点吧. 必胜点和必败点的概念: P点:必败点,换而言之,就是谁处于此位置,则在双方操作正确的情况下必败. N点:必胜点,处于此情况下,双方操作均正 ...

  3. (组合游戏)SG函数与SG定理详解

    文章目录 前言 什么是组合游戏 必胜点和必败点的概念 Sprague-Grundy(SG)定理 SG函数 前言   好久没写博客了,上一篇博客还是去年实训写的,一是因为寒假,二是因为随着难度的加深,学 ...

  4. 组合博弈游戏 - SG函数和SG定理

    转载来自:http://blog.csdn.net/luomingjun12315/article/details/45555495 在介绍SG函数和SG定理之前我们先介绍介绍必胜点与必败点吧. 必胜 ...

  5. 组合游戏 - SG函数和SG定理

    在介绍SG函数和SG定理之前我们先介绍介绍必胜点与必败点吧. 必胜点和必败点的概念: P点:必败点,换而言之,就是谁处于此位置,则在双方操作正确的情况下必败. N点:必胜点,处于此情况下,双方操作均正 ...

  6. SG函数和SG定理【详解】

    在介绍SG函数和SG定理之前我们先介绍介绍必胜点与必败点吧. 必胜点和必败点的概念: P点:必败点,换而言之,就是谁处于此位置,则在双方操作正确的情况下必败. N点:必胜点,处于此情况下,双方操作均正 ...

  7. 三个常见博弈游戏以及 SG 函数和 SG 定理

    前言 原文章 通过数论或者自然数性质完美解决的三个常见博弈游戏: 博弈 解决方法 Bash Game 同余理论 Nim Game 异或理论 Wythoff Game 黄金分割 Bash Game 描述 ...

  8. 再谈SG函数和SG定理

    今天考了一道博弈论的题,让我重新复习一下SG定理吧. 首先通常的Nim游戏的定义是这样的:有若干堆石子,每堆石子的数量都是有限的,合法的移动是"选择一堆石子并拿走若干颗(不能不拿)" ...

  9. 博弈论-SG函数和SG定理

    1.SG函数和SG定理是一个十分神奇的东西,有了它,绝大部分的博弈都可以被统一到这个上面,都可以使用SG函数解决.是一种解决博弈问题的十分方便的手段. 2.首先给出一些基本的定义:mex运算,这个是作 ...

最新文章

  1. 48个Python练手项目(附详细教程)
  2. 用java单源最短路径问题_单源最短路径-贪心算法
  3. Hibernate学习之hibernate.cfg.xml
  4. html1怎样插入视频,HTML视频教程,第1章 HTML初识
  5. FeatureLayer.FeatureClass.Feature --以及图层最容易理解的讲解;如有巧合,一定是别人抄袭(Arcgis辅助理解)
  6. 时域有限差分法matlab,本科 研究生《时域有限差分法(基于MATLAB)》
  7. NLP学习(七)使用stanford实现句法分析-Python3实现
  8. python爬虫登录微博_[突如其来]python爬虫模拟登录微博
  9. obd协议 混动车_OBD协议
  10. java appdata_纯手写!!转移系统用户资料和更改AppData路径的方法 不接受反驳!...
  11. 每日分享:DNS解析记录
  12. mysql报错1517_错误日志 userenv ID1524 1517
  13. 十一、TN 的本征自洽方法、梯度更新与任意 TN 的收缩
  14. 怎样添加服务器远程角色,添加角色和功能,Windows Server 2012 R2如何安装远程桌面服务...
  15. 数智化时代,驱动企业转型升级的“三驾马车”是什么?
  16. 数字化转型的三个重点方向
  17. 【String-easy】657. Robot Return to Origin 机器人能否回到原点
  18. Android编译系统apk并进行系统签名安装
  19. DGL的Blitz ---- Blitz的如何用DGL建图 (v9.0 版DGL)
  20. eclipse安装m2e

热门文章

  1. Python破解12306图片验证码
  2. 目前所有ewebeditor版本***的漏洞与问题总结
  3. 【3】IMU模块:PA-IMU-460 ROS驱动 + 与GNSS时间同步
  4. SpringCloud分布式框架
  5. k8s containerd集群配置安装完整踩坑教程
  6. 在ARM板子上把玩Tensorflow Lite
  7. 美团网创始人王兴专访:我现在的事业十分和谐
  8. windows清理c盘的三种有效方法
  9. BlockingQueue Interface In Java学习
  10. OpenWrt 系列教程汇总