转载自知乎牛客竞赛——博弈论入门(函数讲解+真题模板)

SG函数

作用

对于一个状态i为先手必胜态当且仅当SG(i)!=0。

转移

那怎么得到SG函数尼。

SG(i)=mex(SG(j))(状态i可以通过一步转移到j)

首先说一下mex。一个集合的mex是最小的没有出现在这个集合里的非负整数。

其实想一下这个也是挺明显的。状态i是先手必败态当前仅当i转移到的状态都是先手必胜态。同样,只要当前状态可以转移到一个先手必败态,那么当前就是先手必胜态。

小定理

对于两个独立的游戏A,B,他们的SG函数=SG(A) ^ SG(B)(其实这个也是有SG函数的定义保证的)

这个比较难描述,看一下后面的题就明白了。

Nim游戏

level 1

传送门

有N堆石子。A B两个人轮流拿,A先拿。每次只能从一堆中取若干个,可将一堆全取走,但不可不取,拿到最后1颗石子的人获胜。假设A B都非常聪明,拿石子的过程中不会出现失误。给出N及每堆石子的数量,问最后谁能赢得比赛。

分析:

这就是上面那个小定理的应用了。考虑只有一堆石子的情况,肯定是先手必胜态。

SG函数肯定是石子个数(由SG的定义,显然)。

那么整个游戏的SG函数就是每个子游戏(只有一堆石子的情况)SG函数的异或之和。

所以这个题只要判断所有石子个数异或和是不是0即可。

level 2

有一堆共n个石子,Alice和Bob轮流从这堆石子里面取1到k个,不能取者输。问是否存在先手必胜策略

分析:

状态i可以转移到的状态就是i-j(1<=j<=k)

所以SG(i)=mex(SG(i-j)) (1<=j<=k)

假设k=3

则SG(0)=0,SG(1)=1,SG(2)=2,SG(3)=3,SG(4)=0,SG(5)=1...

可见,当 i%k==1时,SG(i)=0.

仔细想一下就能发现为啥了。这就相当于拿个长度为k的窗口在这个序列里面滑动。新进来的数的SG函数就是刚好从窗口的出去的那个。即先手拿x颗时,后手拿 (k+1-x) 颗。

level 3

有一堆n个石子,Alice和Bob轮流这堆石子里面取石子,每次可以取l-r个,问是否存在先手必胜态。

分析:

介绍一个通法:找规律!!

假设l=3,r=7

SG=[0,0,0,1,1,1,2,2,2,3,0,0.....]

即前 l 个为0,接着 l+r 个非0。

当然可以写个程序找

#include<bits/stdc++.h>
using namespace std; const int maxn = + ;
int sg[maxn], n;
int L, R; void init_sg()
{
for(int i = ;i < L;i++) sg[i] = ;
for(int i = L;i <= n;i++)
{
set<int>s;
for(int j = L;j <= R;j++)
if(i >= j) s.insert(sg[i-j]);
int t = ;
while(s.count(t)) t++;
sg[i] = t;
}
} int main()
{
L = , R = ;
n = ;
init_sg();
for(int i = ;i < n;i++)
{
printf("%d ", sg[i]);
if(i % (L+R) == (L+R-)) printf("\n");
}
}

可写成SG(i)=i%(l + r) / l,但是要怎么证明呢?

一般可以用数学归纳法证明!

level 4

有n堆石子,第i堆石子有a[i]个,Alice和Bob轮流操作,每次可以从一堆石子里面取任意多个,也可以把一堆石子分成两堆。不能操作者输。问是否存在先手必胜态。

分析

继续找规律!

SG(i)=mex(SG(i - j),SG(i-j) ^ SG(j))

SG(i-j)是从石子里面取j个,SG(i-j)^SG(j)是将石子分成j和i-j两堆。

level 5

有1堆石子,Alice和Bob轮流操作,每次可以从一堆里面取当前个数的因数个(不能是本身),不能操作者(剩下一个)输。问是否存在先手必胜态。

分析:

SG(i) = mex(SG(i-k)) (k|i)

打表如下:

找规律可以发现

SG(i) = __builtin_ctz(i)

也就是i的末尾0的个数

level 6

有1堆石子,Alice和Bob轮流操作,每次可以从一堆里面取与当前个数互质的数字个石子,不能操作者输,问是否存在先手必胜态

分析:

SG(i)=mex(SG(i-j)) (gcd(i,j)=1)

打表如下:

发现,对于偶数,SG为0.

对于奇数,SG为最小质因子的编号(就是最小质因子是第几个质数)

SG函数的理解集应用的更多相关文章

  1. (转载)-关于sg函数的理解

    最近学习了nim博弈,但是始终无法理解sg函数为什么sg[S]=mex(sg[S'] | S->S'),看到一篇博文解释的不错,截取了需要的几章节. 四.Sprague-Grundy数的提出 我 ...

  2. sg函数入门理解

    首先理解sg函数必须先理解mex函数 mex是求除它集合内的最小大于等于0的整数,例:mex{1,2}=0:mex{2}=0:mex{0,1,2}=3:mex{0,5}=1. 而sg函数是啥呢? 对于 ...

  3. sg函数的理解

    sg,是用来判断博弈问题的输赢的,当sg值为0的时候,就是输,不为0就是赢: 在这之前,我们规定一个对于集合的操作mex,表示最小的不属于该集合的非负整数. 举几个栗子:mex{0,1,2}=3,me ...

  4. Light OJ 1199 - Partitioning Game (博弈sg函数)

    D - Partitioning Game Time Limit:4000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu ...

  5. 博弈论进阶之SG函数

    SG函数 个人理解:SG函数是人们在研究博弈论的道路上迈出的重要一步,它把许多杂乱无章的博弈游戏通过某种规则结合在了一起,使得一类普遍的博弈问题得到了解决. 从SG函数开始,我们不再是单纯的同过找规律 ...

  6. HDU1536&&POJ2960 S-Nim(SG函数博弈)

    S-Nim Time Limit: 2000MS   Memory Limit: 65536KB   64bit IO Format: %I64d & %I64u Submit Status ...

  7. 关于sg函数的一些证明

    复习csp2019的时候稍微看了看博弈论,发现自己对于sg函数的理解完全不到位 有些定义甚至想都没想过 于是就口胡了一篇blog来安慰虚弱的自己 Question 1 对于一个满足拓扑性质的公平组合游 ...

  8. 博弈的SG函数理解及模板

    首先定义mex(minimal excludant)运算,这是施加于一个集合的运算,表示最小的不属于这个集合的非负整数.例如mex{0,1,2,4}=3.mex{2,3,5}=0.mex{}=0. 对 ...

  9. hdu 4559 涂色游戏(对SG函数的深入理解,推导打SG表)

    提议分析: 1 <= N <= 4747 很明显应该不会有规律的,打表发现真没有 按题意应该分成两种情况考虑,然后求其异或(SG函数性质) (1)找出单独的一个(一列中只有一个) (2)找 ...

随机推荐

  1. 040 RabbitMq及数据同步02

    1.Spring AMQP (1)简介 Spring有很多不同的项目,其中就有对AMQP的支持: Spring AMQP的页面:http://spring.io/projects/spring-amq ...

  2. Java学习:等待唤醒机制

    等待唤醒机制 线程的状态 NEW   至今尚未启动的线程处于这种状态 RUNNABLE   正在Java虚拟机中执行的线程处于这种状态 BLOCKED 受阻塞并等待某个监视器锁的线程处于这种状态 WA ...

  3. ServerSocketChannel简述

    一.前言 前篇文章中了解了SocketChannel:提供了连接到套接字通道,从某种层面而言,NIO中提供了类似于java.net包中对于网络操作的api的功能.既然已经有连接到Socket套接字的通 ...

  4. 从nsurlsession、Alamofire到moya

    更好的理解(抽象).更少的构建(配置).更方便的表达(语言) 一.iOS系统的网络编程(DSL概念) ios缺省的网络编程只是给出了网络编程的基本概念: urlsession.request.resp ...

  5. 近3年常考的Spring面试题及答案

    1. 一般问题 1.1. 不同版本的 Spring Framework 有哪些主要功能? Version Feature Spring 2.5 发布于 2007 年.这是第一个支持注解的版本. Spr ...

  6. 如何判断两个IP地址是不是处于同一网段?

    个人理解,欢迎指正. 一.要判断两个IP地址是不是在同一个网段,就将它们的IP地址分别与子网掩码做与运算,得到的结果-->网络号,如果网络号相同, 就在同一子网,否则,不在同一子网. 例:假定选 ...

  7. mysql 中 and和or 一起使用和之间的优先级

    SELECT address,job_title,education,SUM(recruiting) FROM commerce_jobs WHERE education = '大专' and ( j ...

  8. xshell连接本地linux虚拟机速度很慢的解决办法

    今天发现用xshell连接centos太慢,网上查询后发现是因为ssh的服务端在连接时会自动检测dns环境是否一致导致的,修改为不检测即可. 修改文件位置:vi /etc/ssh/sshd_confi ...

  9. tf.random_shuffle()函数解析

    tf.random_shuffle(value, seed=None, name=None) 函数就是随机地将张量沿第一维度打乱 value:将被打乱的张量. seed:一个 Python 整数.用于 ...

  10. logback配置和使用

    简介 logback是由log4j创始人设计的又一个开源日志组件.当前分成三个模块: logback-core是其它两个模块的基础模块. logback-classic是log4j的一个 改良版本.此 ...