第三十七章 数论——博弈论(1)

news/2024/11/17 16:00:02/

第三十七章 数论——博弈论(1)

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

一、Nim游戏

1、题目

在这里插入图片描述

2、结论

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

3、结论验证

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

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

证明:
请添加图片描述


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

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

证明:

如果我取出石子,必定会让某堆的石子数目发生变化,不变化的时候,抑或结果是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、思路—SG()函数

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

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

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

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

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

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

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

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

那么我们对每堆石子都进行上述的操作,然后画出nnn个图,然后我们对每个图的起点的SG()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.ppmy.cn/news/7644.html

相关文章

【jrebel and xrebel问题记录】激活时出现LS client not configued

教程目录问题描述所使用的环境和版本解决过程手动下载jrebel结束语问题描述 笔者在重装另一台电脑的时候又遇到了这个安装jrebel and xrebel进行激活的问题 但是我在网上找了很多的办法&#xff08;其实都是相同的办法&#xff0c;只是在尝试别人不同的用于激活的服务器&#…

【3】Go语言的数据类型

数据类型 在Go中每一种数据都定义了明确的数据类型&#xff0c;不同的数据类型在内存中分配了不同大小的内存空间。Go的数据类型分为两大块&#xff1a;基本数据类型和派生/复杂数据类型 基本数据类型 整型&#xff1a;123123浮点型&#xff1a;123.123复数&#xff1a;123.1…

C++GUI之wxWidgets(6)-一步步做zip精灵(1)

目录一步步做zip精灵头文件应用类声明框架类声明创建MyApp实例OnInit()事件表OnAbout一步步做zip精灵 头文件 #include <wx/wx.h>应用类声明 // application class class ZipApp : public wxApp { public:// function called at the application initializationvirtua…

插槽,依赖注入,动态组件,异步组件,内置组件

插槽&#xff1a;父组件和子组件内容的一个通信 子组件使用<slot>接收父组件传入的内容 如果内容有多个标签时&#xff0c;使用<template>包裹 默认插槽&#xff1a; <template v-slot:default><h2>标题</h2><p>插槽内容</p> <…

python实现字幕雨效果实现

先看最终实现的效果图&#xff1a; 使用python实现以上字幕雨效果&#xff0c;用到的主要库是pygame&#xff1b; pygame不是内置模块&#xff0c;需要先安装一下&#xff1a; 安装pygame 安装方式推荐有很多种&#xff0c;推荐使用pip&#xff1b; pip 是 Python 的包安装程…

搭建开源版个人图床

在微博图床、gitee、jsDelivr 陆续被 ban 的今天&#xff0c;很有必要搭建自己的图床系统了。 兰空图床 兰空图床官网&#xff1a;https://www.lsky.pro docker版本&#xff1a;https://hub.docker.com/r/halcyonazure/lsky-pro-docker 本次讲解使用 docker 版本进行部署使用 …

前端接入keycloak的几种方式

方式一&#xff1a;keycloak-js 这种方式就像使用QQ登录一样&#xff0c;登录会跳转到 keycloak 给的登录界面。 安装&#xff1a; npm i keycloak-js使用&#xff1a; import Keycloak from keycloak-jsconst keycloak: any Keycloak({url: https://xxx.com/, // 远程地址…

阿里妈妈内容风控模型预估引擎的探索和建设

作者&#xff1a;徐雄飞、金禄旸、滑庆波、李治 内容作为营销的重要载体&#xff0c;能够促进信息的交流和传播。在营销场景中&#xff0c;广告高曝光的特性放大了风险外漏带来的一系列问题&#xff0c;因此对内容的风控审核就显得至关重要。本文将为大家分享阿里妈妈内容风控模…