博弈论中的SG函数】的更多相关文章

SG函数的定义: g(x) = mex ( sg(y) |y是x的后继结点 ) 其中mex(x)(x是一个自然是集合)函数是x关于自然数集合的补集中的最小值,比如x={0,1,2,4,6} 则mex(x)=3: 什么是后继结点? 所谓后继结点就是当前结点经过一个操作可以变成的状态.比如对于娶4石子游戏,假如每次可以取的数目是1,2,4,当前的石子数目也就是当前状态是5,那么5的后继结点就是{5-1, 5-2, 5-4}={4,3,1}: 如果5的三个后继结点的SG函数值分别为0,1,3,那么5的…
SG函数 个人理解:SG函数是人们在研究博弈论的道路上迈出的重要一步,它把许多杂乱无章的博弈游戏通过某种规则结合在了一起,使得一类普遍的博弈问题得到了解决. 从SG函数开始,我们不再是单纯的同过找规律等方法去解决博弈问题,而是需要学习一些博弈论中基本的定理,来找到他们的共同特点 那么就先介绍几个最基本的定理(也可以叫常识)吧 基本定理 ICG游戏 1.游戏有两个人参与,二者轮流做出决策.且这两个人的决策都对自己最有利. 2.当有一人无法做出决策时游戏结束,无法做出决策的人输.无论二者如何做出决策…
在算法竞赛中,博弈论题目往往是以icg.通俗的说就是两人交替操作,每步都各自合法,合法性与选手无关,只与游戏有关.往往我们需要求解在某一个游戏或几个游戏中的某个状态下,先手或后手谁会胜利的问题.就比如经典的:几堆石子,两人可以分别拿若干个,一次只能选择一个石子堆操作,问给定状态下,先手胜利还是后手胜利? 而nim与sg函数就是对于这类问题的解法,在我的理解看来,sg函数和nim分别对应不同阶段的决策:前者对于单个游戏决策,后着是将这些单个游戏综合起来的整体决策. 一.状态与转移 icg游戏往往可…
讲解见此博客https://blog.csdn.net/strangedbly/article/details/51137432 理解Nim博弈,基于Nim博弈理解SG函数的含义和作用. 学习求解SG函数的各种方法 SG函数求解博弈问题速讲 对于一个问题,我们把每一个局面抽象为一个点,那么局面的变化就可以抽象为点之间的有向边. 定义mex为一个集合中未出现的最小的非负数,SG函数g(x)=mex( g(y) ) y为x的所有后继节点. 一个游戏如果有若干个子游戏,每次只能操作其中一个,则游戏的S…
一开始有n个杯子,每个杯子里有一些豆子,两个人轮流操作,每次只能将一个豆子移动到其所在杯子之前的某个杯子里,不过可以移动到的范围只有一段区间.问你是否先手必胜. 一个杯子里的豆子全都等价的,因为sg函数是异或起来的值,所以一个杯子里如果有偶数个豆子,就没有意义. 用sg(i)表示i杯子中的豆子的sg值,sg(i)就是其所能移动到的那段杯子的区间的sg值的mex(未出现的最小非负整数).可以用线段树去做.是经典问题. 由于每次看似是后缀询问,实则是全局询问,故而主席树完全是多余的. 回顾一下区间m…
以后这种题还是不能空想,必须打个表看看,规律还是比较好找的……具体是啥看代码.用SG函数暴力的部分就不放了. #include<cstdio> using namespace std; int T,N,B,n; int main() { freopen("powers.in","r",stdin); scanf("%d",&T); for(;T;--T) { int ans=0; scanf("%d",&a…
仅有距根节点为奇数距离的节点的石子被移走对答案有贡献,∵即使偶数的石子被移走,迟早会被再移到奇数,而奇数被移走后,不一定能够在移到偶数(到根了). 最多移L个:石子数模(L+1),比较显然,也可以自己跑一跑奇数层的SG函数. #include<cstdio> using namespace std; #define N 10001 int en,v[N],first[N],next[N]; void AddEdge(int U,int V) { v[++en]=V; next[en]=firs…
由于异或运算满足结合律,我们把当前状态的SG函数定义为 它所能切割成的所有纸片对的两两异或和之外的最小非负整数. #include<cstdio> #include<set> #include<cstring> using namespace std; int n,m,SG[201][201]; int sg(int x,int y) { if(SG[x][y]!=-1) return SG[x][y]; set<int>S; for(int i=2;i&l…
某个状态的SG函数被定义为 除该状态能一步转移到的状态的SG值以外的最小非负整数. 有如下性质:从SG值为x的状态出发,可以转移到SG值为0,1,...,x-1的状态. 不论SG值增加与否,我们都可以将当前所有子游戏的SG值异或起来从而判断胜负状态. 常采用记忆化搜索来计算SG函数. #include<cstdio> #include<set> #include<cstring> using namespace std; int fib[1001],a[3],SG[10…
http://poj.org/problem?id=3533 变成三维的nim积..前面hdu那个算二维nim积的题的函数都不用改,多nim积一次就过了...longlong似乎不必要但是还是加上了 代码 #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<iostream> #include<map> #include<…
打表找规律即可. 1,1,2,2,2,3,3,3,3,4,4,4,4,4... 注意打表的时候,sg值不只与剩下的石子数有关,也和之前取走的方案有关. //#include<cstdio> //#include<set> //#include<cstring> //using namespace std; //bool vis[16]; //int n,SG[16][1<<16]; //int sg(int x,int moved) //{ // if(SG…
将整个游戏可以划分成若干个互不相交的子游戏. 每个子游戏的sg值只与其中的数的个数有关.而这个数不会超过30. 于是可以预处理出这个sg值表. 然后从1到n枚举,对<=sqrt(n)的部分,用个set判重. 对于大于sqrt(n)的部分,统计其中不包含在之前已经划分出来的子游戏内的数的个数,如果是奇数,就再异或上1. /* #include<cstdio> #include<cstring> #include<set> #include<map> us…
#include<cstring> #include<cstdio> #include<algorithm> #include<set> using namespace std; int m,n; int SG[1000001]; int sg(int x) { if(SG[x]!=-1) return SG[x]; if(!x) return SG[x]=0; set<int>S; int maxv=0,minv=2147483647; int…
一开始就必胜的特判一下. #include<cstdio> #include<cstring> #include<set> #include<algorithm> using namespace std; int T,n,X[1001],Y[1001],SG[101][101]; int sg(int x,int y) { if(SG[x][y]!=-1) return SG[x][y]; set<int>S; for(int i=1;i<…
因为第i个瓶子里的所有豆子都是等价的,设sg(i)表示第i个瓶子的sg值,可以转移到sg(j)^sg(k)(i<j<n,j<=k<n)的状态. 只需要考虑豆子数是奇数的瓶子啦,因为如果豆子数是偶数,重复异或是没有意义的. 对于方案数什么的……枚举就好了. #include<cstdio> #include<cstring> #include<set> using namespace std; int T,n,a[21],SG[21]; int s…
枚举第一步可能达到的状态,判断是否是必败态即可. #include<cstdio> #include<set> #include<cstring> using namespace std; int SG[1001],a[1001],b[1001],n,m,all; int sg(int x) { if(SG[x]!=-1) return SG[x]; set<int>S; for(int i=1;i<=m;++i) { if(b[i]>x) br…
瞎扯 \(orzorz\) \(cdx\) 聚聚给我们讲了博弈论.我要没学上了,祝各位新年快乐.现在让我讲课我都不知道讲什么,我会的东西大家都会,太菜了太菜了. 马上就要回去上文化课了,今明还是收下尾再稍微开一波多项式吧,不然万一文化课上自闭了被锤自闭了站教室外面没课听了还能有事情做--所以把这两天学到的东西稍微整理一下,以后再慢慢完善好了. 发现博弈论的题目还是 \(Nim\) 博弈和其他的比较多.这次就先简单整理一些 \(Nim\) 博弈的类型和东西吧,主要是以某博客里搜来的一串题目为引导.…
[hdu1536][poj2960]S-Nim 题意 题意就是给出一个数组h,为每次可以取石子的数目. 然后给你n堆石子每堆si.求解先手能不能赢? 分析 根据\(h\)数组预处理出\(sg[i]\)表示\(i\)个石子对应的\(sg\)值. 然后\(sg[s_1]\otimes sg[s_2]\otimes ...\otimes sg[s_n]\)即可. 小结 SG函数的使用,通常是ICG模型上不只存在一个石子. 如果只存在一个,可以简化SG函数,直接用布尔值代替.这样的普适性虽然没这么高,但…
SG函数: 给定一个有向无环图和一个起始顶点上的一枚棋子,两名选手交替的将这枚棋子沿有向边进行移动,无法移 动者判负.事实上,这个游戏可以认为是所有Impartial Combinatorial Games的抽象模型.也就是说,任何一个ICG都可以通过把每个局面看成一个顶点,对每个局面和它的子局面连一条有向边来抽象成这个“有向图游戏”.下 面我们就在有向无环图的顶点上定义Sprague-Garundy函数.首先定义mex(minimal excludant)运算,这是施加于一个集合的运算,表示最…
今天初步学习了一下博弈论……感觉真的是好精妙啊……希望这篇博客可以帮助到和我一样刚学习博弈论的同学们. 博弈论,又被称为对策论,被用于考虑游戏中个体的预测行为和实际行为,并研究他们的应用策略.(其实这句话没有什么卯月) 在OI中,博弈论的主要应用是一些经典的模型,以及sg函数,sj定理的应用. 首先我们来看博弈论最为经典的模型之一:Nim游戏 有n堆石子,每次可以从其中任意一堆石子中取出若干块石子(可以取完),不能不取. 最后无石子可取者为输家.假设两人都按最优情况走,问是否先手必胜. 为了计算…
写这篇博客之前,花了许久时间来搞这个SG函数,倒是各路大神的论文看的多,却到底没几个看懂的.还好网上一些大牛博客还是性价比相当高的,多少理解了些,也自己通过做一些题加深了下了解. 既然是博弈,经典的NIM游戏不得不提一下,这也是要不断提醒自己别忘了NIM游戏才是SG函数由来的核心关键! 1. 若干堆石头. 2. 甲和乙轮流从任意堆中取任意个石头. 3. 谁不能取就输. 分析: 对于一个博弈来说,P-position表示previous,代表先手必败,即后手必胜,N-position表示next,…
博弈死我了……(话说哪个小学生会玩博弈论提到的这类弱智游戏,还取石子) 先推荐两个文章链接:浅谈算法——博弈论(从零开始的博弈论) 博弈论相关知识及其应用 This article was updated at 2019.8.14. SG函数 在学习博弈论之前,你需要彻底了解 SG 函数. 对于一个两人轮流操作的游戏,我们把游戏的每一种可能的局面设为一种局面. 那么局面只分两种:(对于这一轮操作者的)必胜态和必败态.至于为什么没有不确定态,看完下文你就明白了. 若这一轮操作者从这个局面出发,按最…
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天这篇是算法与数据结构专题的第27篇文章,我们继续深入博弈论问题.今天我们要介绍博弈论当中非常重要的一个定理和函数,通过它我们可以解决许多看起来杂乱无章的博弈问题,使得我们可以轻松地解决一大类博弈问题. 有了SG函数和SG定理,我们不再是单纯地通过构思.分析和找规律去解决问题了.并且我们之前学过的巴什博奕.威佐夫博弈以及Nim博弈都可以使用SG函数来解决,相当于我们找到了这一大类问题的通解.下面,我们来看几个基本定理和基本概念. 基本…
说到自己,就是个笑话.思考问题从不清晰,sg函数的问题证明方法就在眼前可却要弃掉.不过自己理解的也并不透彻,做题也不太行.耳边时不时会想起alf的:"行不行!" 基本的小概念 这里我们讨论的是公平游戏(ICG游戏:Impartial Combinatorial Games),满足: 1.双方每步的限制相同(轮流) 2.游戏有尽头 对于当前局面的玩家如果能有必胜策略,那就是N局面(反之,P局面) SG函数 每一种决策以及后面的所有可能可以抽象成有向无环图,而sg函数的计算就类似图上dp的…
1188: [HNOI2007]分裂游戏 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 973  Solved: 599[Submit][Status][Discuss] Description 聪聪和睿睿最近迷上了一款叫做分裂的游戏. 该游戏的规则试: 共有 n 个瓶子, 标号为 0,1,2.....n-1, 第 i 个瓶子中装有 p[i]颗巧克力豆,两个人轮流取豆子,每一轮每人选择 3 个瓶子.标号为 i,j,k, 并要保证 i < j ,…
参考链接: http://blog.sina.com.cn/s/blog_51cea4040100h3l9.html 这篇主要就是讲anti-sg.multi-sg和every-sg的. 例1 poj3537 有一个长度为n的一维棋盘,两人轮流下子,如果一个人下了连在一起的三个子就立刻赢了,如果一个人下不了子了他就输了.3<=n<=2000 我们可以发现,如果我们在第i个地方落子,游戏就被分解为了两个子游戏:长度为i-3和n-i-2的两个子游戏.(至于为什么我也不好解释啊,就是如果之后都在这些…
这个标题是不是看起来很厉害呢... 我们首先来看一个最简单的游戏.比如我现在有一堆石子,有p个,每次可以取走若干个(不能不取),不能取的人就输了. 现在假设有两个人要玩这个游戏,一个人先手,一个人后手,假设两个人都是足够聪明的AI,那么谁会赢? 显然p≠0时先手赢,他只要全部取完就行了... 我们先不管这个游戏有多傻逼,我们看一看这个游戏所隐含的模型. 比如我们把当前游戏局面抽象成一个点,把这个点往每下一步可以到达的新状态连一个边,这样就形成了一个有向无环图.(如果有环这个游戏就不会结束了) 现…
Description 聪聪和睿睿最近迷上了一款叫做分裂的游戏. 该游戏的规则试: 共有 n 个瓶子, 标号为 0,1,2.....n-1, 第 i 个瓶子中装有 p[i]颗巧克力豆,两个人轮流取豆子,每一轮每人选择 3 个瓶子.标号为 i,j,k, 并要保证 i < j , j < = k 且第 i 个瓶子中至少要有 1 颗巧克力豆,随后这个人从第 i 个瓶子中拿走一颗豆 子并在 j,k 中各放入一粒豆子(j 可能等于 k) .如果轮到某人而他无法按规则取豆子,那么他将输 掉比赛.胜利者可以…
巴什博奕: 两个顶尖聪明的人在玩游戏,有n个石子,每人可以随便拿1−m个石子,不能拿的人为败者,问谁会胜利 结论: 设当前的石子数为\(n=k∗(m+1)\)即\(n%(m+1)==0\)时先手一定失败 HDU1846 #include<iostream> using namespace std; int main() { int C,N,M; scanf("%d",&C); while(C--) { scanf("%d%d",&N,&a…
目录 预备知识 普通的Nim游戏 SG函数 预备知识 公平组合游戏(ICG) 若一个游戏满足: 由两名玩家交替行动: 游戏中任意时刻,合法操作集合只取决于这个局面本身: 若轮到某位选手时,若该选手无合法操作,则这名选手判负: 则称该游戏为一个公平组合游戏. Nim游戏 有若干堆石子,每堆石子的数量都是有限的,合法的移动是"选择一堆石子并拿走若干颗(不能不拿)",如果轮到某个人时所有的石子堆都已经被拿空了,则判负(因为他此刻没有任何合法的移动). mex(minimal exdudant…