第三十七章 数论——博弈论

news2024/12/25 14:23:32

第三十七章 数论——博弈论

  • 一、Nim游戏
    • 1、题目
    • 2、结论
    • 3、结论验证
    • 4、代码
  • 二、台阶——Nim游戏
    • 1、问题
    • 2、思路
    • 2、代码
  • 三、集合——Nim游戏
    • 1、问题
    • 2、思路—SG()函数
    • 2、代码实现(记忆化搜索)

一、Nim游戏

1、题目

在这里插入图片描述

2、结论

这里直接说结论
假设有 n n n堆石子,对于第 i i i堆石子,石子个数是 a i a_i ai
那么我们可以通过以下结论判断先手是否必赢:
请添加图片描述

3、结论验证

当石子都是0的时候,那么一堆0抑或起来还是0,如果有一个人面对这种情况,那么必定是先手必输的状态。从这个特殊的情况出发,我们也能验证一下为什么抑或为0,先手必输。

我们可以简单验证一下结论:
我们主要从两个角度入手,

先手必赢状态必定可以让对手为先手的时候,所面对的局面是必输状态。

证明:
请添加图片描述


第二件事我们要验证的就是,

我本身处于先手必输的状态,当轮到对方的时候,对方不可能也面对必输的状态。

证明:

如果我取出石子,必定会让某堆的石子数目发生变化,不变化的时候,抑或结果是0,变化之后抑或结果一定不是0。

如果我拿走了石子抑或结果还是0,那么说明我拿走前后该堆石子数目没变,说明我拿了0个,但是这是违法操作。

既然不可能是0,那么对方面对的就一定是必赢的状态。

4、代码

代码实现的话,我们只要看抑或结果是不是0就行了。

#include<iostream>
using namespace std;
int main()
{
    int res=0;
    int n=0;
    cin>>n;
    while(n--)
    {
        int a;
        scanf("%d",&a);
        res^=a;
    }
    if(res)puts("Yes");
    else puts("No");
}

二、台阶——Nim游戏

1、问题

在这里插入图片描述

2、思路

首先,如果台阶上没有石子了,那么这些 0 0 0抑或起来就是0,因此如果有一个先手的时候面对这个情况,那么一定是先手必输的状态,所以我们这里还是可以使用我们刚刚的结论来判断是否先手必赢。

那么对于这道题而言,我们只需要保持奇数阶上的石子抑或起来为不为0即可

为什么呢?

假设我处于先手必赢的状态,即奇数阶上的石子抑或不为0,那么根据之前的nim结论,我们一定可以将部分石子从奇数阶拿到偶数阶,让对手处于先手必败的状态。

此时,对手处于先手必败的状态,它能否打破呢?

如果对手从偶数阶向奇数阶拿石子,那么此时抑或起来就不是0了,那么轮到我操作的时候,我依旧是先手必赢。我只需要将对手从偶数阶拿到奇数阶的石子,再从奇数阶拿到偶数阶,此时我就又能保证对手处于先手必输的状态。

如果对手从奇数阶向偶数阶拿石子,此时该奇数阶的石子个数记录为x,此时抑或起来不是0,轮到我操作,我可以再对一个奇数阶进行操作,让这个台阶的石子也变成x,此时二者抑或又成了0。这样又可以让对手成为先手必败的状态。

但是偶数阶就不一样了,假设我们的结论是保持偶数阶上的石子抑或起来为不为0即可。
如果我处于先手必败的状态,那么必定存在这样一种情况,当第一级台阶不为0的时候,我可以把第一级台阶上的石子扔到地上,此时偶数阶不变,对手就变成了先手必败。但根据我们之前的证明,必败态是没法让自己赢的,先手必败转移给了对方这是不合理的。

所以,偶数阶只是我们缓冲的一个平台,奇数阶才决定了是否获胜。

2、代码

#include<iostream>
using namespace std;
int main()
{
    int n;
    cin>>n;
    int res=0;
    for(int i=1;i<=n;i++)
    {
        int a;
        scanf("%d",&a);
        if(i%2)res^=a;
    }
    if(res)puts("Yes");
    else puts("No");
}

三、集合——Nim游戏

1、问题

在这里插入图片描述

2、思路—SG()函数

我们这里再引入一个 S G ( ) SG() SG()函数的概念,而这个函数的定义需要根据一个有向无环图定义。

我们知道,我们比赛时的每一个状态都可以看作一个点,我们的操作可以看作一个有向边,经过有向边,我们可以到达下一个状态。

我们看下面这个图:请添加图片描述
我们把最终状态变成0,而这里还是要用到我们的nim中的结论。

如果我处于了最终的状态,意思就是我无法进行操作了,那么就说明处于一种必输的状态,所以我们把所有的终点都标记成0。

然后,我们倒退,上一个节点的 S G ( ) SG() SG()函数值等于一个最小的大于等于0值,并且这个最小的自然数值不能是它所有可能的下一个状态的 s g ( ) sg() sg()的函数值。比如,一个节点连接着 s g ( ) sg() sg()函数值为 0 , 1 , 2 0,1,2 0,1,2的点,那么当前的点就只能取 3 3 3,如果所连的点是 1 , 2 1,2 1,2,那么我可以是 0 0 0

s g ( ) sg() sg()函数的意义同刚刚的结论一样:

如果函数值是0,说明当前是先手必输状态,如果函数值非0,说明当前的状态是先手必赢状态。

那么如我们的每一堆都可以画出这样一个图,那么思路就是,我们根据操作画出所有的情况,构成一个有向无环图,然后逆推 S G ( ) SG() SG()函数。如下图:
请添加图片描述

那么我们对每堆石子都进行上述的操作,然后画出 n n n个图,然后我们对每个图的起点的 S G ( ) SG() SG()函数值进行抑或操作,看最终是否等于0,等于0说明先手必输,不等于0说明先手必赢。

请添加图片描述

2、代码实现(记忆化搜索)

#include <cstring>
#include <iostream>
#include <unordered_set>
using namespace std;
const int N = 110, M = 10010;
int n, m;
int s[N], f[M];
int sg(int x)
{
    if (f[x] != -1) return f[x];
    unordered_set<int> St;
    for (int i = 0; i < m; i ++ )
    {
        int sum = s[i];
        if (x >= sum) St.insert(sg(x - sum));
    }
    for (int i = 0; ; i ++ )
        if (!St.count(i))
            return f[x] = i;
}
int main()
{
    cin >> m;
    for (int i = 0; i < m; i ++ ) cin >> s[i];
    cin >> n;
    memset(f, -1, sizeof f);
    int res = 0;
    for (int i = 0; i < n; i ++ )
    {
        int x;
        cin >> x;
        res ^= sg(x);
    }
    if (res) puts("Yes");
    else puts("No");
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/128178.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue导入私有组件和注册全局组件

目录先下载并配置插件导入私有组件注册全局组件先下载并配置插件 导入的时候需要路径,有个符号,但不能提示路径,需要手打路径,会发现很麻烦,这时候可以通过vscode插件来解决 vscode搜索Path Autocomplete 配置插件,点击插件设置—扩展设置,点开任意一个setting.json中编辑,打开…

Yield Guild Games 和 Axie Infinity:迄今为止的旅程

2022 年&#xff0c;菲律宾被认为是全球应用 web3 的中心&#xff0c;在 Chainalysis 的全球加密货币应用指数中排名第二&#xff0c;在拥有最多 MetaMask 用户的国家中排名第三。虽然该国作为 Coins.ph 和 BloomX 等开创性数字资产交易所以及对加密货币友好的 UnionBank 的所在…

Flutter生命周期

一、组件生命周期 flutter组件只有两种&#xff1a;有状态和无状态组件。由于无状态组件效率高&#xff0c;如果不涉及到组件内部的数据存储&#xff0c;尽量多的使用无状态组件 1、StatelessWidget build&#xff1a;组件渲染 调用次数&#xff1a;1次 StatelessWidget是无状…

MYSQL索引和sql优化

基本 索引是帮助数据高效查询的有序数据结构&#xff0c;没有索引进行查询就会进行全表扫描myisam中的.MYI和innodb中的.idb都是存放索引的文件。索引提高查询效率的同时&#xff0c;也降低了更新表的数据&#xff0c;因为数据库中删改查会维护索引的结构。一般提到的索引就是…

安装mysqlclient失败解决办法

简介 系统&#xff1a;MAC 前因&#xff1a;django使用mysql数据库报错django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module.Django使用MySQL数据库需要加载 MySQLdb模块&#xff0c;需要安装 mysqlclient&#xff08;django2.2以前安装pymysql&#…

ipsec 建立正常后业务端口测试通过但是业务访问故障

某公司ipsec 分支和总部对接成功后&#xff0c;检查发现两端业务测试正常。分支和总部服务器可以互访&#xff0c;分支测试总部服务器80端口开放正常&#xff0c;排除两侧因策略的影响。但是总部服务器web业务和数据库业务均出现无法访问&#xff0c;web页面打不开&#xff0c;…

Es初步检索命令

1、_cat GET /_cat/nodes&#xff1a;查看所有节点 请求 &#xff1a; http://192.168.107.129:9200/_cat/nodes 响应 &#xff1a; 127.0.0.1 15 95 8 0.19 0.16 0.24 dilm * 32bb46713f1b GET /_cat/health&#xff1a;查看 es 健康状况 请求 &#xff1a; http://192.16…

kali - 通过抓包获取FTP连接密码

数据来源 开始实验 实验目标&#xff1a;在win2003主机部署一台FTP服务器&#xff0c;然后winXP通过账户密码连接2003主机的FTP服务器&#xff0c;kali虚拟机抓取数据包获取密码。 实验拓补图 实验流程&#xff1a; 1、开启虚拟机并配置IP 我这里开了一台Kali、一台window…

elmentUI组建中el-date-picker实现限制时间范围精确到小时

elmentUI组建中el-date-picker实现限制时间范围精确到小时 需求要求 时间选择器只能选择今天之前的日期.默认时间是前一天00点~23点后台返回的最小时间和最大时间时间精度限制到小时 开始想着用type"datetimerange"来实现,后来发现控制时间禁用无法实现,后改变思路…

SkyEye助力飞控软件Debug

​01.Debug是什么&#xff1f; 1947年9月9日&#xff0c;美国著名科学家格蕾丝.霍普&#xff08;Grace Hopper&#xff09;与其同伴在对Mark II计算机进行研究时发现&#xff0c;导致计算机无法正常工作的罪魁祸首居然是一只粘在继电器上的小飞蛾。格蕾丝用镊子将飞蛾夹出&…

在腾讯、阿里、字节技术岗工作十年能挣普通公务员一辈子的钱吗?

在腾讯、阿里、字节技术岗工作十年&#xff0c;能挣到普通公务员一辈子的钱&#xff0c;但不一定能存到普通公务员一辈子的钱。 大厂程序员 VS 普通公务员谁更香&#xff0c;一直是争论不断的话题&#xff0c;让我们站在程序员的角度&#xff0c;来回答这一问题。 大厂程序员V…

打造智慧社区数字孪生应用新范式

近日&#xff0c;民政部、中央政法委、中央网信办、国家发展改革委等部门印发了《关于深入推进智慧社区建设的意见》&#xff0c;明确指出依托智慧社区综合信息平台&#xff0c;创新政务服务、公共服务提供方式&#xff0c;推动就业、健康、卫生、等服务“指尖办”、“网上办”…

家装市场“攻守道”

不同于很多属于弹性需求的消费行业&#xff0c;“住”属于刚性需求&#xff0c;因此家装就成为了人们日常生活中的重要交易场景。据《疫情下的家居消费心态调查》问卷显示&#xff0c;60%以上的居民不会因为疫情而放弃装修。大量的装修需求激发了家装的活力&#xff0c;家装市场…

Node.js 模块化(二) 开发包/模块加载机制

1. 开发属于自己的包 1. 需要实现的功能 2. 初始化包的基本结构 3. 初始化 package.json 属性&#xff1a; name&#xff1a;包的名称&#xff08;不能重复&#xff0c;在官网检索一下&#xff0c;避免重复&#xff09; version&#xff1a;版本号 main&#xff1a;入口文件&a…

如何下载并生成等高线

如何下载并生成等高线 发布时间&#xff1a;2018-01-17 版权&#xff1a; 同步视频教程&#xff1a;下载高程等高线使用视频教程-Bigemap GIS Office 专题地图制作视频教程&#xff1a;地图数据应用&#xff08;制作地图效果的基本过程&#xff09;-Bigemap GIS Office 视频…

【vue】关于路由的使用

&#xff08;1&#xff09;路由步骤 根据官方的文档&#xff0c;我们的路由大概需要以下的几种构成 &#xff08;1&#xff09;首先引入组件 &#xff08;2&#xff09;创建routes布局 &#xff08;3&#xff09;创建router对象 &#xff08;4&#xff09;抛出 &#xff0…

最长公共子序列

最长公共子序列一、题目二、思路1、状态转移方程&#xff08;1&#xff09;状态表示&#xff08;2&#xff09;状态转移2、循环设计三、代码一、题目 二、思路 这道题是一个很经典的DP问题&#xff0c;那么我们来看一下如何分析。 DP问题我们需要考虑两个问题&#xff1a;第一…

【Javassist】快速入门系列11 当检测到显示类型转换时用代码块替换

系列文章目录 01 在方法体的开头或结尾插入代码 02 使用Javassist实现方法执行时间统计 03 使用Javassist实现方法异常处理 04 使用Javassist更改整个方法体 05 当有指定方法调用时替换方法调用的内容 06 当有构造方法调用时替换方法调用的内容 07 当检测到字段被访问时使用语…

深度剖析钓鱼网站域名识别工具dnstwist

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,科大讯飞比赛第三名,CCF比赛第四名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

漫途设备远程运维平台在制造业中的应用!

我国正处于从制造大国向制造强国迈进的关键时期&#xff0c;制造业的数字化、网络化、智能化以及绿色制造体系&#xff08;双碳为代表&#xff09;的打造事关制造业全局&#xff0c;是制造业高质量、可持续发展的关键与重要着力点。而设备智能运维是智能制造行业的短板。 存在以…