说到自己,就是个笑话。思考问题从不清晰,sg函数的问题证明方法就在眼前可却要弃掉。不过自己理解的也并不透彻,做题也不太行。耳边时不时会想起alf的:“行不行!”

基本的小概念

  • 这里我们讨论的是公平游戏(ICG游戏:Impartial Combinatorial Games),满足:

    1.双方每步的限制相同(轮流)

    2.游戏有尽头
  • 对于当前局面的玩家如果能有必胜策略,那就是N局面(反之,P局面)

SG函数

  • 每一种决策以及后面的所有可能可以抽象成有向无环图,而sg函数的计算就类似图上dp的过程。
  • 若当前的局面是now,下一步的局面为to

    \(SG[now]=Mex(SG[to])\)

    \(Mex(S)\)表示,最小的没有在\(S\)集合里的非负整数

    这就是SG的定义了,这很迷糊,因为它就是一个当前局面的估价,很难说它具体是什么意义(甚至后面还会用它来运算就离谱)
  • 显然的性质

    1.SG[now]后面存在了sg为0的局面,now就为N局面,你接下来你的操作也会move到\(sg[to]=0\)这种局面。

    2.1的反之。

    3.SG为0表示当前局面P,否则为N。(ps.三个点就是一个结论,3总结1,2)
  • Muiti-SG的性质(见nim游戏后)

nim游戏

  • 这是最基本最重要的游戏,理解它后,你将入门博弈。
  • 规则:两个人玩nim游戏,有n堆石子,每堆有\(a_i\)个,每次可从一堆中取走任意多个石子。如果一个人无石子可取就输。
  • 结论:\(xorsum\ =\ a_1\ xor\ a_2\ xor\ a_3\ xor\ ...\ xor\ a_n\)是0就为P局面,否则N局面。
  • 证明:如果xorsum=0,取后xorsum!=0; 如果xorsum!=0,一定存在从一堆(堆i)取走\(a_i-xorsum\ xor\ a_i\)个石子,使取后\(xorsum=0\)

    然后最终输的状态为全0,这是xorsum=0的。而如果一开始为xorsum=0一定被拿捏,一直xorsum=0直到输掉(对面就一直使你xorsum=0)
  • 这时,你肯定会想:用sg暴力做呢?状态存不下啊。当然就引出了后面有关sg的重要推论……

    不过对于只有一堆(或者想成n堆每堆独立)\(sg[i]=i\)的。(i为还剩的石子个数)

重要推论

  • 从上面,或许我们能猜想:

    S局面被拆分成\(n\)个相互独立的小局面,(我们这里叫S为\(s_1->s_n\)的游戏和,满足:

    \(SG[S]\ =\ SG[s_1]\ xor\ SG[s_2]\ ....\ xor\ SG[s_n]\)

    这个对于公平游戏来讲,居然是正确的。证明?->
  • 证明:

    我们通常遇到博弈想最终态(P态为多,因为sg=0)

    当然是所有sg值全为0的时候。

    你每次只能转移一个小局面(一堆石子),它能转移到0~sg[i]-1以及sg[i]+k,k是不确定的。

    你发现如果没有sg[i]+k我们可以用nim游戏来证明。

    如果有,相当于加石子,实质上还是符合nim游戏证明中的异或和总是=0和!=0相交替。

    加和减因此也没有实质区别,就得证。
  • ps.老板告诉我们可以把任何ICG问题转化为相同sg值(=石子个数)的nim游戏。

小结:

nim类,或者ICG类都感觉核心就用到以上几个结论。不过我太菜了,还是做不来题。博弈论还有很多值得探索,不过现实中人也没有那么理性,很多时候也用不到。

有趣题目:

1.字符游戏

  • 思路:首先01串+构造长度为L+前缀关系,很容易想到trie树

    因为“互异”,所以每次更新trie树从根开始的一条链,链叶的子树里的点下次就不可以被选择了。

    然后我们通过画图找规律,然后每个点的SG值为lowbit(子树深度),画一下就知道了
  • 代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
typedef long long ll;
int go[N][2],nd;
ll lowbit(ll u) {return u&(-u);}
ll ans=0;
char s[N];
void Insert() {
int u=0,len=strlen(s);
for(int i=0;i<len;i++) {
int x=s[i]-'0';
if(!go[u][x]) go[u][x]=++nd;
u=go[u][x];
}
}
void dfs(int u,ll dep) {
if(go[u][0]) dfs(go[u][0],dep-1);
else ans^=lowbit(dep);
if(go[u][1]) dfs(go[u][1],dep-1);
else ans^=lowbit(dep);
}
int main() {
int n;ll l;
scanf("%d%lld",&n,&l);
for(int i=1;i<=n;i++) {
scanf("%s",s);
Insert();
}
dfs(0,l);
if(ans)printf("Alice");
else printf("Bob");
return 0;
}

博弈论(nim游戏,SG函数)的更多相关文章

  1. BZOJ 1874: [BeiJing2009 WinterCamp]取石子游戏 [Nim游戏 SG函数]

    小H和小Z正在玩一个取石子游戏. 取石子游戏的规则是这样的,每个人每次可以从一堆石子中取出若干个石子,每次取石子的个数有限制,谁不能取石子时就会输掉游戏. 小H先进行操作,他想问你他是否有必胜策略,如 ...

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

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

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

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

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

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

  5. 博弈论进阶之SG函数

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

  6. BZOJ1188 [HNOI2007]分裂游戏(SG函数)

    传送门 拿到这道题就知道是典型的博弈论,但是却不知道怎么设计它的SG函数.看了解析一类组合游戏这篇论文之后才知道这道题应该怎么做. 这道题需要奇特的模型转换.即把每一个石子当做一堆石子,且原来在第i堆 ...

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

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

  8. HDU 1536 S-Nim (组合游戏+SG函数)

    题意:针对Nim博弈,给定上一个集合,然后下面有 m 个询问,每个询问有 x 堆石子 ,问你每次只能从某一个堆中取出 y 个石子,并且这个 y 必须属于给定的集合,问你先手胜还是负. 析:一个很简单的 ...

  9. HDU 3032 Nim or not Nim? (sg函数)

    Nim or not Nim? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  10. Wannafly挑战赛23 T2游戏 SG函数

    哎,被卡科技了,想了三个小时,最后还是大佬给我说是\(SG\)函数. \(SG\)函数,用起来很简单,证明呢?(不可能的,这辈子都是不可能的) \(SG\)定理 游戏的\(SG\)函数就是各个子游戏的 ...

随机推荐

  1. Android实现蓝牙远程连接遇到的问题

    主要问到的问题:1.uuid获取不到,一直为空,后来发现android4.2之前使用uuid这种方法,目前尽量不使用uuid方式 2.socket.connect()出错,报read failed, ...

  2. java中为什么把Checked Exception翻译成受检的异常?

    6.Checked Exception(受检的异常) 马克-to-win:为什么我大胆的把Checked Exception翻译成受检的异常?因为这类异常,编译器检查发现到它后会强令你catch它或t ...

  3. iOS全埋点解决方案-控件点击事件

    前言 ​ 我们主要介绍如何实现控件点击事件($AppClick)的全埋点.在介绍如何实现之前,我们需要先了解一下,在 UIKit 框架下,处理点击或拖动事件的 Target-Action 设计模式. ...

  4. Installing github.com/mdempsky/gocode FAILED ----vscode安装go插件中的一些坑

    问题前景: 最近在使用vscode,编写一些go的代码,但发现调试的时候,会需要安装很多插件,但通过vscode之间安装的话,会出现如下的错误: Installing github.com/mdemp ...

  5. 更改docker默认的data,metadata存储大小(实操)

    为什么要更改 data,metadata呢?我们运行环境中涉及大量数据操作,数据增长有时候很快,由于之前规划不足,所以磁盘很快达到瓶颈需要进行重新部署.这就需要调整原来的一些docker配置.操作系统 ...

  6. oracle查看当前用户表结构、主键、索引

    1.查询表的所有列及其属性 select t.*,c.COMMENTS from user_tab_columns t,user_col_comments c where t.table_name = ...

  7. Sqlalchemy异步操作不完全指北

    异步SQLAlchemy SQLAlchemy作为一款通用的Python Orm工具,在最近的版本也支持了异步操作.但网上很多资料都不是很齐全,API也不是很好查询的情况下,我便有了整理一份基础文档的 ...

  8. 1.Markdown语法

    Markdown学习 一.标题:(# +标题名字) 标题 三级标题 四级标题 二.字体 (空格内容前后的空格删掉) Hello,World! **粗体** Hello,World! *斜体* Hell ...

  9. SQL语言学习-DQL

    DQL:查询表中的记录 * select * from 表名; 1. 语法: select 字段列表 from 表名列表 where 条件列表 group by 分组字段 having 分组之后的条件 ...

  10. XCTF练习题---MISC---快乐游戏题

    XCTF练习题---MISC---快乐游戏题 flag:UNCTF{c783910550de39816d1de0f103b0ae32} 解题步骤: 1.观察题目,下载附件 2.还真是一个游戏,赢了就得 ...