【ACM博弈论】SG函数入门(1):从巴什博奕到尼姆游戏

yizhihongxing

在我小时候以前做题的时候,遇到博弈题往往都是漫无目的地打表找规律,或者找一些特殊情况但是没有很好的分析方法。

其实博弈题是有比较套路的解题方法的,那就是利用SG函数,第一节不会讲到SG函数的具体用法,我们先来博弈入个门,学习一下最基本的博弈类型:Nim游戏

? 作者:Eriktse
? 简介:19岁,211计算机在读,现役ACM银牌选手?力争以通俗易懂的方式讲解算法!❤️欢迎关注我,一起交流C++/Python算法。(优质好文持续更新中……)?
? 阅读原文获得更好阅读体验:https://www.eriktse.com/algorithm/1110.html

巴什博奕

在进入Nim游戏之前,我们先看一个简单的博弈:巴什博奕

看这道例题:http://acm.hdu.edu.cn/showproblem.php?pid=1846

由于HDUOJ经常打不开,我这里复制一下题意:

1、 本游戏是一个二人游戏;
2、 有一堆石子一共有n个;
3、 两人轮流进行;
4、 每走一步可以取走1…m个石子;
5、 最先取光石子的一方为胜;
如果游戏的双方使用的都是最优策略,请输出哪个人能赢。

假设此时的n = 10, m = 3,我们来分析一下这个局面。

我们设一个布尔函数f(x),表示当n = x时的输赢。

  • f(0) = 0,因为无法继续操作了,显然是0,也就是说这是一个必败态。
  • f(1) = 1,可以取走一个石子,使对手陷入必败态,所以这是一个必胜态。
  • f(2) = 1,可以取走两个。
  • f(3) = 1,可以取走三个。
  • f(4) = 0,无论取走一个、两个或三个都必然使得对手进入必胜态,所以这是一个必败态。
  • f(5) = 1
  • f(6) = 1
  • f(7) = 1
  • f(8) = 0,无论取走一个、两个或三个都必然使得对手进入必胜态,所以这是一个必败态。
  • f(9) = 1
  • f(10) = 1

至此,我们得到了答案,f(n) = f(10) = 1所以先手必胜,不难发现上面这个函数f(x)的规律,仅当x % 4 == 0时为0,其余情况都为1

于是我们只需要判断n % (m + 1)是否为0就能判断先手是否获胜。

这就是巴什博奕模型,是不是很简单,我们简单打个表就找到了规律。

Nim游戏

依然看这道例题:https://www.luogu.com.cn/problem/P2197

我们这么分析:

败局一定是全为0的情况,此时所有数字的异或和为0(不知道怎么写异或和的latex,大家凑合着看):

\[\oplus_{i=1}^{n}a_i = 0
\]

那么想一下那些状态可以到这个败局呢?我们反向的思考,往任意一个位置加上一个数字,就可以作为前一个状态,也就是一个必胜态(因为那个状态必然可以到达败局的状态)。

往任意一个位置加上一个数字之后就必然有:

\[\oplus_{i=1}^{n}a_i \ne 0
\]

再想一下,从一个异或和不为0的状态,是否一定有办法转移到一个异或和为0的状态。

不难发现是一定可以的。

举个栗子:

我们有4堆石子,数量分别为:1 7 2 6。这是我随便写的一个数据。

它们的异或和为:1 ^ 7 ^ 2 ^ 6 = (0 1 0),那么我可以通过调整2 -> 0使得异或和为0,现在有1 ^ 7 ^ 0 ^ 6 = 0,当然我还可以通过6 -> 4,异或和结果也是0。

不难发现,只需要从数组中找一个最高非零位大于等于异或的结果的最高非零位的数字,然后减少一部分就可以,这样的数是一定存在的。

那么也就是说任意一个异或和非零的状态都可以通过一步转移到异或和为0的状态,任意一个异或和为0的状态不管怎么走一步,都必然转移到异或和非0的状态

而石子的个数是一直减小的,最终一定会走到全0,异或和为0的状态且一定是败局。

也就是说:

必胜态W(win):异或和非0;
必败态L(lose):异或和为0;

以上就是Nim游戏模型,当然你也可以叫他Nim博弈

这一节先了解这些,下一节将会讲解SG函数的转移和子游戏的合并。

? 本文由eriktse原创,创作不易,如果对您有帮助,欢迎小伙伴们点赞?、收藏⭐、留言?

原文链接:https://www.cnblogs.com/eriktse/p/17302621.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:【ACM博弈论】SG函数入门(1):从巴什博奕到尼姆游戏 - Python技术站

(0)
上一篇 2023年4月17日
下一篇 2023年4月17日

相关文章

  • C语言进阶数据的存储机制完整版

    C语言进阶数据的存储机制完整版攻略 1. 前言 C语言是一门高度可控的语言,其中其数据的存储机制是必须掌握的基础知识点。本文介绍了C语言数据存储的机制,包括变量在内存中的分配、指针的应用及结构体的组织等内容,旨在帮助读者掌握C语言中的数据存储机制。 2. 变量在内存中的分配 变量在内存中的分配既涉及到内存的分配可操作性,也涉及到相应的存储结构。 2.1. 变…

    数据结构 2023年5月17日
    00
  • MySQL底层数据结构选用B+树的原因

    MySQL底层数据结构选用B+树的原因主要是因为B+树具有以下优点: 能够快速查找B+树的查找速度非常快,时间复杂度为O(log n),在海量数据的环境中,能够快速定位目标数据。因为B+树每次查找只需要遍历树高度的次数,即使数据量很大,树的高度也很小。 能够高效地进行增删改操作B+树的平衡性能够保证树的高度非常小,大部分操作只需要遍历树的高度,而不是整颗树,…

    数据结构 2023年5月17日
    00
  • Python数学建模PuLP库线性规划入门示例详解

    以下是关于“Python数学建模PuLP库线性规划入门示例详解”的完整攻略: 简介 PuLP是一个Python库,用于线性规划问题的建模和求解。本教程将介绍如何使用PuLP库解决线性规划问题。 步骤 1. 安装PuLP 首先,我们需要安装PuLP库。可以使用以下命令在Python中安装PuLP: !pip install pulp 2. 导入库 接下来,我们…

    python 2023年5月14日
    00
  • 图解AVL树数据结构输入与输出及实现示例

    请允许我为您详细讲解“图解AVL树数据结构输入与输出及实现示例”的完整攻略。 标题 AVL树数据结构简介 AVL树是一种平衡二叉搜索树,是由G.M. Adelson-Velsky和E.M. Landis在1962年发明的。它的特点是带有平衡条件,任意节点的左右子树高度差不超过1,通过左旋、右旋、左右旋、右左旋四种形态的调整操作,来维护树的平衡。这样可以保证树…

    数据结构 2023年5月17日
    00
  • python实现决策树C4.5算法详解(在ID3基础上改进)

    Python实现决策树C4.5算法详解(在ID3基础上改进) 决策树是一种常见的机器学习算法,它可以用于分类和回归问题。C4.5算法是一种基于信息增益比的决策树算法,它在ID3算法的基础上进行了改进,可以处理连续属性和缺失值。在本文中,我们将介绍如何使用Python实现C4.5算法,并详细讲解实现原理。 实现原理 C4.5算法的实现原理比较复杂,我们可以分为…

    python 2023年5月14日
    00
  • C语言数据结构之单链表的查找和建立

    C语言数据结构之单链表的查找和建立 什么是单链表? 单链表是一种常见的数据结构,是由若干个节点(Node)组成的链式结构,每个节点存储着链表中的元素和指向下一个节点的指针。 单链表的优点是插入、删除元素简单,但是查找元素比较困难。 在C语言中,我们可以使用结构体来定义一个节点: struct ListNode { int val; struct ListNo…

    数据结构 2023年5月17日
    00
  • 浅谈Python数学建模之整数规划

    下面是详细讲解“浅谈Python数学建模之整数规划”的完整攻略。 1. 什么是整数规划 整数规划是一种数学优化问题,它要求满足一约束条件的情况下,找到一组整数解,得目标函数取得最大或最小值。整数规划在实际用中经常用于生产调度、资源分配、物流配送等领域。 2. Python实现整数规划 Python中多种可以实整数规划,以下是其中两种常用方法。 2.1 使用P…

    python 2023年5月14日
    00
  • Java数据结构常见几大排序梳理

    Java数据结构常见几大排序梳理 在Java中,数据排序是非常常见的操作。下面我们详细讲解一下Java数据结构常见几大排序的梳理。 常见几大排序 Java数据结构中常见几种排序算法包括: 冒泡排序(Bubble Sort) 快速排序(Quick Sort) 插入排序(Insertion Sort) 选择排序(Selection Sort) 希尔排序(Shel…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部