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值就是集合{0,1,3}的补集的最小元素,也就是2。

关于整个游戏的sg值之和sum,定义sum=sg1 ^ sg2 ^ sg3 ^ ……sgn.  其中^表示按位异或运算。

结论:一个游戏的初始局面是必败态当且仅当sum=0。

一篇非常好的关于SG值的论文:http://www.cnitblog.com/weiweibbs/articles/42735.html

SG值打表模板:

//f[]:可以取走的石子个数
//sg[]:0~n的SG函数值
//hash[]:mex{}
int f[N],sg[N],hash[N];
void getSG(int n)
{
int i,j;
memset(sg,0,sizeof(sg));
for(i=1;i<=n;i++)
{
memset(hash,0,sizeof(hash));
for(j=1;f[j]<=i;j++)
hash[sg[i-f[j]]]=1;
for(j=0;j<=n;j++) //求mes{}中未出现的最小的非负整数
{
if(hash[j]==0)
{
sg[i]=j;
break;
}
}
}
}

HDU1848

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1848

题意:取石子问题,一共有3堆石子,每次只能取斐波那契数个石子,先取完石子者胜利,问先手胜还是后手胜

  1. 可选步数为一系列不连续的数,用GetSG(计算)
  2. 最终结果是所有SG值异或的结果
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1001;
//f[] 可以取走的石子数
//sg[] 0~n的sg函数值
//hash[] mex{}
int f[maxn],sg[maxn],hash[maxn];
void getsg(int n)
{
memset(sg,0,sizeof(sg));
for(int i=1;i<=n;i++)
{
memset(hash,0,sizeof(hash));
for(int j=1;f[j]<=i;j++)
hash[sg[i-f[j]]]=1;
for(int j=0;j<=n;j++)
{
if(hash[j]==0)
{
sg[i]=j;
break;
}
}
}
}
int main()
{
int n,m,k;
f[0]=f[1]=1;
for(int i=2;i<=16;i++)
f[i]=f[i-1]+f[i-2];
getsg(1000);
while(cin>>n>>m>>k)
{
if(!n&&!m&&!k)
break;
int sum=0;
sum=sg[n]^sg[m]^sg[k];
if(sum==0)
cout<<"Nacci"<<endl;
else
cout<<"Fibo"<<endl;
}
return 0;
}

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

  1. 博弈论进阶之SG函数

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

  2. 博弈论基础之sg函数与nim

    在算法竞赛中,博弈论题目往往是以icg.通俗的说就是两人交替操作,每步都各自合法,合法性与选手无关,只与游戏有关.往往我们需要求解在某一个游戏或几个游戏中的某个状态下,先手或后手谁会胜利的问题.就比如 ...

  3. 博弈论初步(SG函数)

    讲解见此博客https://blog.csdn.net/strangedbly/article/details/51137432 理解Nim博弈,基于Nim博弈理解SG函数的含义和作用. 学习求解SG ...

  4. 【博弈论】【SG函数】【线段树】Petrozavodsk Summer Training Camp 2016 Day 9: AtCoder Japanese Problems Selection, Thursday, September 1, 2016 Problem H. Cups and Beans

    一开始有n个杯子,每个杯子里有一些豆子,两个人轮流操作,每次只能将一个豆子移动到其所在杯子之前的某个杯子里,不过可以移动到的范围只有一段区间.问你是否先手必胜. 一个杯子里的豆子全都等价的,因为sg函 ...

  5. 【博弈论】【SG函数】【找规律】Gym - 101147A - The game of Osho

    以后这种题还是不能空想,必须打个表看看,规律还是比较好找的……具体是啥看代码.用SG函数暴力的部分就不放了. #include<cstdio> using namespace std; i ...

  6. 【博弈论】【SG函数】bzoj1777 [Usaco2010 Hol]rocks 石头木头

    仅有距根节点为奇数距离的节点的石子被移走对答案有贡献,∵即使偶数的石子被移走,迟早会被再移到奇数,而奇数被移走后,不一定能够在移到偶数(到根了). 最多移L个:石子数模(L+1),比较显然,也可以自己 ...

  7. 【博弈论】【SG函数】poj2311 Cutting Game

    由于异或运算满足结合律,我们把当前状态的SG函数定义为 它所能切割成的所有纸片对的两两异或和之外的最小非负整数. #include<cstdio> #include<set> ...

  8. 【博弈论】【SG函数】hdu1848 Fibonacci again and again

    某个状态的SG函数被定义为 除该状态能一步转移到的状态的SG值以外的最小非负整数. 有如下性质:从SG值为x的状态出发,可以转移到SG值为0,1,...,x-1的状态. 不论SG值增加与否,我们都可以 ...

  9. POJ 3553 Light Switching Game 博弈论 nim积 sg函数

    http://poj.org/problem?id=3533 变成三维的nim积..前面hdu那个算二维nim积的题的函数都不用改,多nim积一次就过了...longlong似乎不必要但是还是加上了 ...

随机推荐

  1. VIM键盘图

  2. 关于Linux内核学习的一点点总结

    关于Linux内核学习的一点点总结 关键词:Linux, 操作系统,内核 博客列表 由反汇编C程序来理解计算机是如何工作的 通过分析一个简化版时间片轮转多道程序内核代码来认识操作系统中的进程调度 通过 ...

  3. oracle 启动监听报错TNS-12547: TNS:lost contact

    https://blog.csdn.net/liqfyiyi/article/details/7534018

  4. django学习之- 动态验证码学习

    实例:通过前台和后台,实现用户登录页面动态图片验证码校验,图片验证码部分使用Pillow模块实现,作为单独学习部分记录. 前端: <!DOCTYPE html> <html lang ...

  5. python学习之-- 进程 和 线程

    python 进程/线程详解 进程定义:以一个整体的形式暴露给操作系统管理,它里面包含对各种资源的调用,内存的管理,网络接口的调用等等,对各种资源管理的集合,就可以叫做一个进程. 线程定义:线程是操作 ...

  6. Unique Binary Search Trees(dp)

    Given n, how many structurally unique BST's (binary search trees) that store values 1...n? For examp ...

  7. Python pandas学习笔记

    参考文献:<Python金融大数据分析> #导入模块 import pandas as pd #生成dataframe df = pd.DataFrame([10,20,30,40], c ...

  8. SQL 主机

    SQL 主机 SQL 主机 如果您想要您的网站存储数据在数据库并从数据库显示数据,您的 Web 服务器必须能使用 SQL 语言访问数据库系统. 如果您的 Web 服务器托管在互联网服务提供商(ISP, ...

  9. Mybatis加入Ehcache支持

    1.Mybatis默认的缓存配置 MyBatis 包括一个很强大的查询缓存特性,它能够很方便地配置和定制. Mybatis缓存包括全局的缓存和局部的缓存.全局的缓存能够讲主配置文件的setting属性 ...

  10. 关于Scrum

    最近某些产品经理发出下两周的工作计划的时候,喜欢带上sprint这个字眼,看上去貌似是要走敏捷开发这一套,只可惜,我觉得他表现出来的是对敏捷开发和Scrum一窍不通,甚至对软件开发流程都完全不清楚,居 ...