最近在数学这一块搞了蛮多题目,已经解决了数论基础,线性代数(只有矩阵,行列式待坑),组合数学中的一些简单问题。所以接下来不可避免的对博弈论这一哲学大坑开工。

当然,由于我很,所以也只能从最基础最容易的部分讲起了。

这次主要介绍两个基本模型:Bash Game&&Nim Game,还是比较经典的

下面开始讲

1.Bash Game

Bash Game(巴什博弈)是一种零基础的入门题目,它的基本模型大概是这样的:

一堆石子共n个,两人轮流从中取石子,规定每次至少取一个,最多取m个,最后取光者得胜。问两人博弈,他们都采用最聪明的策略,问最后谁可以必胜。

首先我们从小开始分析:

  • 当m>=n时,先手可以一把抓完石子,这样先手必胜

  • 当n=m+1时,先手无论怎么抓,都会留下1~m个石子,这样后手一把就可以抓完,这样先手必败

  • 当m+1<n<2*(m+1)时,先手只要抓适当的石子就可以剩下m+1个石子,然后后手必输,那么先手必胜

  • 当n=2*(m+1)时,后手可以采取这种策略,当先手抓x个时,后手就抓m+1-x个,这样就会把m+1的情况送给先手,那么先手必败

  • ......

所以通过上面的分析我们很容易得出:当n%(m+1)==0时,先手必败;否则先手必胜

这个很简单吧,因为谁先面对k*(m+1)(k为正整数)这种局面就必定失败。因为一方可以每次让你们两个取得石子和为m+1导致另一方失败。

这个问题还有一些变形,比较经典的就是:把一个数从0开始不断增加,每次增加的范围都是1~k,谁先让数增加到n就Win||Lose

这个直接转化为Bash Game做一下即可

这里给几道例题&&CODE(以下例题都来自HDU

1846

Bash博弈的板子题,直接上即可

CODE

#include<cstdio>
using namespace std;
int t,n,m;
inline char tc(void)
{
static char fl[100000],*A=fl,*B=fl;
return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
x=0; char ch=tc();
while (ch<'0'||ch>'9') ch=tc();
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc();
}
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
read(t);
while (t--)
{
read(n); read(m);
puts(n%(m+1)?"first":"second");
}
return 0;
}

2149

这就是那种变式的情况,我们转化一下在做转化个屁,至于输出方案的话特判一下即可

CODE

#include<cstdio>
using namespace std;
int n,m;
inline void write(int x)
{
if (x/10) write(x/10);
putchar(x%10+'0');
}
int main()
{
register int i;
while (scanf("%d%d",&m,&n)!=EOF)
{
if (n>=m)
{
for (i=m;i<n;++i)
write(i),putchar(' '); write(n); putchar('\n');
} else
if (m%(n+1)) write(m%(n+1)),putchar('\n'); else puts("none");
}
return 0;
}

2138

同上,Bash Game直接上即可

CODE

#include<cstdio>
using namespace std;
int t,n,m;
inline char tc(void)
{
static char fl[100000],*A=fl,*B=fl;
return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
x=0; char ch=tc();
while (ch<'0'||ch>'9') ch=tc();
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc();
}
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
read(t);
while (t--)
{
read(n); read(m);
puts(n%(m+1)?"Grass":"Rabbit");
}
return 0;
}

4764

这道题就注意一下大于等于n你就输了,所以n要减一

CODE

#include<cstdio>
using namespace std;
int n,m;
inline char tc(void)
{
static char fl[100000],*A=fl,*B=fl;
return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
x=0; char ch=tc();
while (ch<'0'||ch>'9') ch=tc();
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc();
}
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
for (;;)
{
read(n); read(m);
if (!n&&!m) break;
puts((n-1)%(m+1)?"Tang":"Jiang");
}
return 0;
}

2.Nim Game

这其实是Bash Game的进化版,但是思维深度上了好几个台阶

首先我们看基本模型:

地上有n堆石子,每人每次可从任意一堆石子里取出任意多枚石子扔掉,可以取完,不能不取。每次只能从一堆里取。最后没石子可取的人就输了。假如甲是先手,且告诉你这n堆石子的数量,他想知道是否存在先手必胜的策略。

这是不是很复杂,首先我们考虑数据小的情况:

  • 只有一堆石子时,除非没有石子,否则先手一把抓完即可

  • 有两堆石子时,后手只需要跟随先手的动作即可

  • ......(后面的根本分析不出来好吧)

但是在我们之前已经有大神成功证明了一个神奇的结论

当n堆石子的数量异或和等于0时,先手必败,否则先手必胜

证明请移步至attack dalao's blog

很懵逼对吗其实我也是,那么让我们来感性理解一下(以下的说明仅为个人理解,几乎没有任何理论依据,请选择阅读)

首先由于全部都是0的时候就失败了,所以我们可以认为当它们的异或和为0就是必败态

这样我们先手是如果异或和为0那么就输了

如果不是呢,我们就可以通过一种猥琐的方法来获胜(就是上面讲的方法)

我们可以形象地认为它与Bash Game中先手先取得只剩下k*(m+1)然后通过让和始终为m+1来取胜

然后这就是神奇的Nim Game

这里有一道模板题Luogu P2197 nim游戏

由于就是裸的Nim Game,这里就直接上CODE了

#include<cstdio>
using namespace std;
int t,n,x,tot;
inline char tc(void)
{
static char fl[100000],*A=fl,*B=fl;
return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
x=0; char ch=tc();
while (ch<'0'||ch>'9') ch=tc();
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc();
}
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
register int i; read(t);
while (t--)
{
for (read(n),tot=0,i=1;i<=n;++i)
read(x),tot^=x;
puts(tot?"Yes":"No");
}
return 0;
}

当然这只是博弈论的入门,一些真正强力的东西如SG函数&&MINMAX等东西还是一脸懵逼

浅谈博弈论中的两个基本模型——Bash Game&&Nim Game的更多相关文章

  1. 浅谈Java中的equals和==(转)

    浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str ...

  2. 浅谈Linux中的信号处理机制(二)

    首先谢谢 @小尧弟 这位朋友对我昨天夜里写的一篇<浅谈Linux中的信号处理机制(一)>的指正,之前的题目我用的“浅析”一词,给人一种要剖析内核的感觉.本人自知功力不够,尚且不能对着Lin ...

  3. 浅谈Java中的对象和引用

    浅谈Java中的对象和对象引用 在Java中,有一组名词经常一起出现,它们就是“对象和对象引用”,很多朋友在初学Java的时候可能经常会混淆这2个概念,觉得它们是一回事,事实上则不然.今天我们就来一起 ...

  4. 浅谈Java中的equals和==

    浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: String str1 = new String("hello"); String str2 = ...

  5. 转【】浅谈sql中的in与not in,exists与not exists的区别_

    浅谈sql中的in与not in,exists与not exists的区别   1.in和exists in是把外表和内表作hash连接,而exists是对外表作loop循环,每次loop循环再对内表 ...

  6. 浅谈iOS中的userAgent

    浅谈iOS中的userAgent   User-Agent(用户代理)字符串是Web浏览器用于声明自身型号版本并随HTTP请求发送给Web服务器的字符串,在Web服务器上可以获取到该字符串. 在公司产 ...

  7. 浅谈JavaScript中的闭包

    浅谈JavaScript中的闭包 在JavaScript中,闭包是指这样一个函数:它有权访问另一个函数作用域中的变量. 创建一个闭包的常用的方式:在一个函数内部创建另一个函数. 比如: functio ...

  8. 浅谈sql中的in与not in,exists与not exists的区别

    转 浅谈sql中的in与not in,exists与not exists的区别   12月12日北京OSC源创会 —— 开源技术的年终盛典 »   sql exists in 1.in和exists ...

  9. 浅谈Java中的深拷贝和浅拷贝(转载)

    浅谈Java中的深拷贝和浅拷贝(转载) 原文链接: http://blog.csdn.net/tounaobun/article/details/8491392 假如说你想复制一个简单变量.很简单: ...

随机推荐

  1. 使Volley完美支持自定义证书的Https

    其实在最早的版本里,Volley甚至是不支持https协议的,只能跑http,当然你也可以自己修改他的源码让他支持,如今volley的代码经过一些改进以后, 已经可以完美支持https协议了,无论是在 ...

  2. Mongodb的入门(8)mongodb事物分析

    老生常谈:<在前面博客中也介绍过> mongodb官网:https://docs.mongodb.com/manual/introduction/ mongodb:官网上是这样定义的Mon ...

  3. JavaWeb:jsp

    本文内容: JSP的介绍 jsp的使用 EL表达式 JSTL的使用 首发日期:2018-06-18 JSP的介绍: JSP全称Java Server Pages. 与静态网页格式的html不同的是,j ...

  4. Scrapy爬取遇到的一点点问题

    学了大概一个月Scrapy,自己写了些东东,遇到很多问题,这几天心情也不大好,小媳妇人也不舒服,休假了,自己研究了很久,有些眉目了 利用scrapy 框架爬取慕课网的一些信息 步骤一:新建项目 scr ...

  5. Ubuntu18.04 更换源

    在虚拟机新建一个Ubuntu18.04.1-live-server-amd64当做服务器 在安装软件时报错: slave@slave:~$ sudo -s[sudo] password for sla ...

  6. .NetCore Build Terminology

       .NETCore Command:    1.dotnet build 2.dotnet run 3.dotnet new classlib 4.dotnet new xunit 5.dotne ...

  7. system函数的应用

    system函数的两个简单应用 1.调用cmd命令.例:(打开计算器) #include <stdlib.h> int main() { system("calc"); ...

  8. 在Eclipse中使用Maven jetty的debug模式

    1.右键项目debug as添加mvn命令: jetty:run 2.进入eclipse的菜单Run->Debug configurations,会看到maven build下对应的项目的mvn ...

  9. FusionCharts参数说明——3D饼图属性(Pie3D.swf )

    animation 是否显示加载图表时的动画palette 内置的图表样式,共5个paletteColors 自定义图表元素颜色(为多个,如过过少会重复)showAboutMenuItem 右键是否显 ...

  10. cf C. Finite or not? 数论

    You are given several queries. Each query consists of three integers pp, qq and bb. You need to answ ...