博弈论

博弈论

简单介绍

就是两个对象在进行某个斗争,按照某种规则,会有先手必赢和后手必赢的局面产生,我们就是要根据不同的规则去研究策略。

然后关于博弈论的话,常见的题目都是公平组合游戏;
公平组合游戏呢…就是游戏人数为2,二者轮流做出决策,且双方都知道游戏规则;任意一个游戏者在某一确定状态可做出的决策集合只与当前状态有关而与游戏者无关;游戏中的状态不可能多次抵达,游戏以玩家无法行动为结束,且游戏一定会在有限步后以非平局结束;

ps:大部分棋类游戏都不是公平组合游戏,像是国际象棋、中国象棋、围棋、五子棋…(因为双方都不能使用对方的棋子)

一些术语理解(建议先看模型)

几种模型均存在奇异局面,即双方均采取最优策略,若处于奇异局面,必败。

所谓奇异局面,就是必败点。

必胜点和必败点的概念:

   P点:必败点,换而言之,就是谁处于此位置,则在双方操作正确的情况下必败。

   N点:必胜点,处于此情况下,双方操作均正确的情况下必胜。

必胜点和必败点的性质:

    1、所有终结点是 必败点 P 。(我们以此为基本前提进行推理,换句话说,我们以此为假设)

    2、从任何必胜点N 操作,至少有一种方式可以进入必败点 P。

    3、无论如何操作,必败点P 都只能进入 必胜点 N。

我们研究必胜点和必败点的目的时间为题进行简化,有助于我们的分析。通常我们分析必胜点和必败点都是以终结点进行逆序分析。

模型

1.巴什博弈(最简单的)

只有一堆n个物品,两人轮流从这堆物品中取物,规定每次至少取一个,最多取m个;最后取光者获胜。

我们来分析一哈:
状况1:n<=m时,先手必赢,因为他一下子就可以拿走全部的物品
状况2:n=m+1时,后手胜。因为先手至少拿一个又不能全拿完,剩下的物品又是<=m的,所以后手可以一下子全部拿完了。
状况3:n=m+2时,先手胜。因为先手可以让后手面对m+1局面即状况2。

依次递推得出结论,当总数为(m+1)的倍数时,后手胜;否则先手胜。

写成代码就是:

if(n % (m + 1) != 0)
            return first win;
else
            return second win;

整个例题 牛客网滴题

2.斐波那契博弈

顾名思义,和斐波那契有关
一堆石子有n个,两人轮流取,先手第一次可以取任意多个但是不能全部取完,之后不论谁去取都最多取上一次取石子数的2倍;取完的人胜出。

先给出结论吧,当n为斐波那契数列时,先手必输。

分析:

代码:

void Init()//斐波那契数列,先打表,范围看情况
{
    f[0]=f[1]=1;
    for(int i=2;i<=55;i++)
    {
        f[i]=f[i-1]+f[i-2];
    }
}
int n;
int flag = 0;
for(int i = 0;f[i];i++){//分别比较,判断出n是否是斐波那契数,其中的f[i]是判断f[i]是否存在,相当于i<=55
    if(f[i] == n){
        flag = 1;
        break;
    }
}
if(!flag)
    return first win;
else
    return second win;

3.威佐夫博弈

有两堆物品,每人轮流从任意一堆中取出至少一个或者同时从两堆中取出同样多的物品,规定每次至少取一个,至多不限,最后取光者获胜。

结论:两物品的初始值为x,y,则令z=abs(x-y);记w=(int)[(sqrt(5)+1)/2*z];若w=min(x,y),则先手必败,否则先手必胜。

分析:

模板:

int z = abs(y-x);
 if((int)(((sqrt(5)+1)/2)*z)!=min(x,y))
     return first win;
 else
     return second win;

例题 牛客网

4.尼姆博弈

有任意堆物品,每堆物品的个数是任意的,双方轮流从中取物品,每一次只能从一堆物品中取部分或全部物品,最少取一件,取到最后一件物品的人获胜。

结论:判断这几堆物品的异或运算结果是否为0,如果为0,则先手必败。

介绍下异或运算:
相当于转换成二进制的且不进位的加法运算,异或运算符为:^
运算规则:参加运算的两个对象,如果两个相应位为“异”(值不同),则该位结果为1,否则为0.
0^0=0;
0^1=1
1^0=1
1^1=0
分析:

模板:

int n;
int a;
int num = 0;
cin >> n;
for(i = 0;i < n;i++){
    cin >> a;
    num ^= a;
}
if(num)
	return first win;
else
	return second win;

例题:
台阶-Nim游戏

现在,有一个n级台阶的楼梯,每级台阶上都有若干个石子,其中第i级台阶上有ai个石子(i≥1)。
两位玩家轮流操作,每次操作可以从任意一级台阶上拿若干个石子放到下一级台阶中(不能不拿)。
已经拿到地面上的石子不能再拿,最后无法进行操作的人视为失败。
问如果两人都采用最优策略,先手是否必胜。

例题分析摘于hcr学长
此时我们需要将奇数台阶看做一个经典的Nim游戏,如果先手时奇数台阶上的值的异或值为0,则先手必败,反之必胜

证明:
先手时,如果奇数台阶异或非0,根据经典Nim游戏,先手总有一种方式使奇数台阶异或为0,于是先手留了奇数台阶异或为0的状态给后手

于是轮到后手:

①当后手移动偶数台阶上的石子时,先手只需将对手移动的石子继续移到下一个台阶,这样奇数台阶的石子相当于没变,于是留给后手的又是奇数台阶异或为0的状态

②当后手移动奇数台阶上的石子时,留给先手的奇数台阶异或非0,根据经典Nim游戏,先手总能找出一种方案使奇数台阶异或为0

因此无论后手如何移动,先手总能通过操作把奇数异或为0的情况留给后手,当奇数台阶全为0时,只留下偶数台阶上有石子。

(核心就是:先手总是把奇数台阶异或为0的状态留给对面,即总是将必败态交给对面)

因为偶数台阶上的石子要想移动到地面,必然需要经过偶数次移动,又因为奇数台阶全0的情况是留给后手的,因此先手总是可以将石子移动到地面,当将最后一个(堆)石子移动到地面时,后手无法操作,即后手失败。

因此如果先手时奇数台阶上的值的异或值为非0,则先手必胜,反之必败!

代码:

int res = 0;
int n;
cin >> n;

for(int i = 1 ; i <= n ; i++)
{
    int x;
    cin >> x;
    if(i % 2) res ^= x;
}
if(res) return first win;
else return second win;

4.SG函数与SG定理

放个链接

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

紫薯C菌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值