爱丽丝和鲍勃一起玩游戏,他们轮流行动。爱丽丝先手开局。

最初,黑板上有一个数字 n 。在每个玩家的回合,玩家需要执行以下操作:

  • 选出任一 x,满足 0 < x < n 且 n % x == 0 。
  • 用 n - x 替换黑板上的数字 n 。

如果玩家无法执行这些操作,就会输掉游戏。

只有在爱丽丝在游戏中取得胜利时才返回 true 。假设两个玩家都以最佳状态参与游戏。

示例 1:

输入:n = 2
输出:true
解释:爱丽丝选择 1,鲍勃无法进行操作。

示例 2:

输入:n = 3
输出:false
解释:爱丽丝选择 1,鲍勃也选择 1,然后爱丽丝无法进行操作

数学归纳法:

class Solution {
public:bool divisorGame(int n) {return n%2==0;  }
};

数学归纳法的核心是:

  1. 基础步:验证 n 取最小的几个值时猜想成立;
  2. 归纳步:假设 n ≤ k 时猜想成立,证明 n = k+1 时猜想也成立。
1. 基础步:n=1 和 n=2 时结论成立
  • n=1(奇数):1 没有小于自身的因数(无法操作),先手必败(符合猜想)。
  • n=2(偶数):2 的因数是 1,先手减去 1 后剩 1,后手无法操作,先手必胜(符合猜想)。
2. 归纳步:假设 n≤k 时成立,证明 n=k+1 时成立

分两种情况讨论 k 的奇偶性(因为 k 和 k+1 奇偶性相反):

情况 1:k 是偶数 → k+1 是奇数
  • n = k+1 是奇数,其所有因数 x 必为奇数(奇数的因数都是奇数)。
  • 先手(Alice)必须减去一个奇数 x,剩余数为 (k+1) - x
    • 奇数减奇数 = 偶数,且 (k+1) - x ≤ k(因为 x ≥ 1)。
    • 根据归纳假设(n ≤ k 时成立),偶数必为必胜态,此时轮到后手(Bob)面对偶数,Bob 必胜。
  • 结论:n=k+1(奇数)时,Alice 必败(符合猜想)。
情况 2:k 是奇数 → k+1 是偶数
  • n = k+1 是偶数,其因数 x 可以是奇数或偶数。
  • 先手(Alice)可以选择减去一个奇数 x,剩余数为 (k+1) - x
    • 偶数减奇数 = 奇数,且 (k+1) - x ≤ k(因为 x ≥ 1)。
    • 根据归纳假设(n ≤ k 时成立),奇数必为必败态,此时轮到后手(Bob)面对奇数,Bob 必败。
  • 结论:n=k+1(偶数)时,Alice 可以通过选择合适的 x 让 Bob 必败,因此 Alice 必胜(符合猜想)。

最终结论

通过数学归纳法,证明了 “偶数时先手必胜,奇数时先手必败” 的猜想成立。

本质逻辑:奇数的因数都是奇数,操作后必然留下偶数(给对手必胜态);而偶数可以通过减去奇数留下奇数(给对手必败态),因此奇偶性直接决定了胜负。

动态规划: 

class Solution {
public:bool divisorGame(int n) {// 创建一个布尔类型数组R,大小为n,用于记录每个数字的先手状态// R[i]表示:当数字为i时,当前玩家(先手)是否能获胜(true为胜,false为败)vector<bool> R(n, false);// 基础情况:// 当数字为1时,没有小于1的因数,先手无法操作,必败R[1] = false;// 当数字为2时,先手可以取因数1,剩余1给对手(对手必败),因此先手必胜R[2] = true;// 从数字3开始,依次推递推计算每个数字的胜负状态for(int i = 3; i < n + 1; i++) {// 枚举当前数字i的所有可能因数j(1 ≤ j < i)for(int j = 1; j < i; j++) {// 核心判断:// 1. j必须是i的因数(i % j == 0)// 2. 取走j后,剩余数字i-j对应的状态为必败(!R[i-j])// 如果存在这样的j,说明当前玩家可以通过取j让对手陷入必败态,因此当前玩家必胜if(i % j == 0 && !R[i - j]) {R[i] = true;  // 标记当前数字i为必胜态break;        // 找到一个有效j即可,无需继续枚举}}}// 返回数字n对应的先手状态(是否必胜)return R[n];}
};

 

通过定义状态 f[i] 记录 “当前数字为 i 时,先手是否必胜”,再从基础情况递推到更大的 i

1. 状态定义
  • f[i] = true:当数字为 i 时,先手必胜
  • f[i] = false:当数字为 i 时,先手必败
2. 递推逻辑(核心)

对于数字 i,先手的胜负取决于其所有可能的下一步操作:

  • 先手可以选择 i 的任意一个因数 j0 < j < i),将数字变为 i-j(此时轮到后手操作,后手面对的状态是 f[i-j]);
  • 如果存在至少一个 j,使得 f[i-j] = false(即后手面对 i-j 时必败),那么先手可以选择这个 j,让后手陷入必败态,因此 f[i] = true(先手必胜);
  • 如果对于所有 j,都有 f[i-j] = true(即后手面对所有可能的 i-j 时都必胜),那么先手无论怎么操作都会让后手必胜,因此 f[i] = false(先手必败)。
3. 基础情况(边界条件)
  • f[0]:无意义(无法操作);
  • f[1]:数字 1 没有小于自身的因数(j 不存在),先手无法操作,必败 → f[1] = false
  • f[2]:因数 j=1,操作后变为 2-1=1,此时后手面对 f[1]=false(必败),因此 f[2] = true(先手必胜)。
4. 递推过程(从前往后计算)

从 i=3 开始,依次计算 f[i]

  • 枚举 i 的所有因数 j0 < j < i);
  • 对每个 j,检查 f[i-j] 是否为 false
  • 只要存在一个 j 满足 f[i-j] = false,则 f[i] = true;否则 f[i] = false

示例说明(以 i=3 为例)

  • i=3 的因数 j 为 1(因为 3 的因数是 1 和 3,但 j < 3,所以只有 j=1);
  • 操作后数字变为 3-1=2,此时后手面对 f[2] = true(后手必胜);
  • 由于所有可能的 j 对应的 f[i-j] 都是 true,因此 f[3] = false(先手必败)。

本质逻辑

  • 博弈问题的核心是 “让对手陷入必败态”;
  • 动态规划通过记录每个状态的胜负,将大问题拆解为小问题(i 的状态依赖于更小的 i-j 的状态);
  • 从基础情况逐步递推,最终可得到任意 n 对应的 f[n],即初始状态下先手的胜负。

 

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一起学springAI系列一:初体验

Spring AI是干嘛的官网最权威&#xff0c;直接粘贴&#xff1a;“Spring AI”项目旨在简化那些包含人工智能功能的应用程序的开发过程&#xff0c;同时避免不必要的复杂性。AI相关领域的功能对python的支持是最好的&#xff0c;相关供应商在出了啥功能的时候&#xff0c;都会优…

Ext JS极速项目之 Coworkee

ExtJS Coworkee 是什么? Ext JS 的 Coworkee 是一个由 Sencha 官方提供的完整员工管理应用示例,旨在展示 Ext JS 框架在企业级应用开发中的能力。 在线试用的地址是: https://examples.sencha.com/coworkee/#home 页面效果与布局 登录页面: 主页效果 左右分区结构:左…

飞算科技:原创技术重塑 Java 开发,引领行业数智化新浪潮

在科技革新的浪潮中&#xff0c;飞算科技作为一家坚持自主创新的数字科技企业&#xff0c;同时也是国家级高新技术企业&#xff0c;正深耕互联网科技、大数据、人工智能等前沿领域&#xff0c;为众多企业的数字化与智能化转型提供强劲动力。​飞算科技的成长轨迹&#xff0c;是…

cesium FBO(一)渲染到纹理(RTT)

一听到三维的RTT&#xff08;Render To Texture&#xff09;&#xff0c;似乎很神秘&#xff0c;但从底层实现一看&#xff0c;其实也就那样&#xff0c;设计API的哪些顶级家伙已经帮你安排的明明白白了&#xff0c;咱们只需要学会怎么用就可以了。我认为得从WebGL入手&#xf…

PNP机器人机器人学术年会展示灵巧手动作捕捉方案。

2025年8月1-3日&#xff0c;第六届中国机器人学术年会&#xff08;CCRS2025&#xff09;在长沙国际会议中心举行&#xff0c;主题“人机共融&#xff0c;智向未来”。PNP机器人与灵巧智能联合展出最新灵巧手模仿学习方案&#xff1a;基于少量示教数据即可快速复现复杂抓取动作&…

【45】C#入门到精通——C#调用C/C++生成动态库.dll及C++ 生成动态库.dll ,DllImport()方式导入 C++动态库.dll方法总结

文章目录1 C 生成动态库.dll2 C#调用C/C生成动态库.dll2.1 [DllImport()] 方式导入 C动态库.dll2.2 调用测试3 C/C 生成通用dll,改进3.1改进后.h3.2 .cpp3.2 C# 调用4 [DllImport()] 方式导入C生成的 .dll 总结4.1 指定路径导入4.2 .dll放在 执行目录下&#xff08;一定要放对&…

从协议栈到ath12k_mac_op_tx的完整调用路径

文章目录 从协议栈到ath12k_mac_op_tx的完整调用路径 1. 整体架构概览 2. 详细调用路径分析 2.1 应用层到Socket层 2.2 协议层处理 2.3 网络设备层到mac80211 2.4 mac80211发送入口 2.5 mac80211核心发送处理 2.6 mac80211发送核心处理 2.7 mac80211发送调度 2.8 最终驱动调用 …

WPFC#超市管理系统(4)入库管理

入库管理7. 商品入库管理7.2 入库实现显示名称、图片、单位7.3 界面设计7.3 功能实现7. 商品入库管理 数据库中StockRecord表需要增加商品出入库Type类型为nvarchar(50)。C#中的数据库重新同步StockRecord表在Entity→Model中新建枚举类型StockType namespace 超市管理系统.E…

CSS 打字特效

效果图.wxml <view class"tips"><text>{{ tipsText }}</text><text class"tips-line">|</text> </view>.wxss .tips{padding: 50rpx 100rpx;font-size: 28rpx; } .tips-line{color: #ccc;animation: tips-line .5s al…

直播小程序 app 系统架构分析

一、引言 直播行业近年来发展迅猛&#xff0c;直播小程序和 APP 成为众多用户获取直播内容以及主播进行内容输出的重要平台。一个完善且高效的系统架构是支撑直播业务稳定运行、提供优质用户体验的关键。本文将详细剖析直播小程序 / APP 的系统架构&#xff0c;包括整体架构设计…

Vue常见题目

1. 什么是 Vue.js&#xff1f;它的核心特点是什么&#xff1f; Vue.js 是一个渐进式 JavaScript 框架&#xff0c;用于构建用户界面。它的核心特点包括&#xff1a; - 响应式数据绑定 - 组件化开发 - 虚拟 DOM - 指令系统 - 轻量级且易于集成 - 丰富的生态系统&#xff08;Vue…

ipynb文件直接发布csdn

第一步&#xff0c;下载markdown文件 file --> save and export notebook as --> markdown第二步&#xff0c;导入markdown文件 进入csdn发布文章界面&#xff0c;点击导入&#xff0c;选择第一步下载的markdown文件即可

广东省省考备考(第六十四天8.2)——判断推理(重点回顾)

判断推理&#xff1a;数量规律 错题解析解析解析解析解析解析解析标记题解析解析解析解析解析解析解析今日题目正确率&#xff1a;53% 判断推理&#xff1a;属性规律 错题解析解析解析解析解析解析标记题解析解析今日题目正确率&#xff1a;60%

【C++/STL】vector的OJ,深度剖析和模拟实现

vector在OJ中的使用 1.只出现一次的数字 class Solution { public:int singleNumber(vector<int>& nums) {int value 0;for(auto e : v) {value ^ e; }return value;} };2.杨辉三角 class Solution { public:vector<vector<int>> generate(int numRow…

衡石湖仓一体架构深度解构:统一元数据层如何破除数据孤岛?

一、数据融合的世纪难题典型困境二、衡石统一元数据层设计架构核心关键技术实现智能元数据发现自动构建跨源血缘关系动态查询重写 将标准SQL翻译为最优执行计划text Original: SELECT SUM(sales) FROM virtual_view Rewritten: [S3] SELECT SUM(amount) FROM crm_sales [My…

Windows 下 fping 指令使用指南

fping 作为一款强大的网络工具&#xff0c;能够同时向多个主机发送 ICMP 回声请求&#xff0c;相较于传统的 ping 命令&#xff0c;在处理大量主机时具有显著优势。 一、fping 简介​ fping 是 “fast pinger” 的缩写&#xff0c;它可以向一系列 IP 地址发送 ICMP 回声请求。…

代码随想录day52图论3

文章目录101. 孤岛的总面积102. 沉没孤岛103. 水流问题104.建造最大岛屿101. 孤岛的总面积 题目链接 文章讲解 #include<bits/stdc.h> using namespace std;int ans 0; // 记录不与边界相连的孤岛数量 int sum 0; // 当前孤岛的面积 bool flag false; /…

linux pip/conda 修改默认cache位置

1 pip pip cache默认在/home/{username}目录下&#xff0c;容易导致系统盘写满报错。查看pip cache位置pip cache dir假设移动pip cache目录到 /data/.cache/pip/cache&#xff0c;命令如下pip config set global.cache-dir /data/.cache/pip/cache2 conda 查看conda缓存位置c…

如何解决pip安装报错ModuleNotFoundError: No module named ‘seaborn’问题

【Python系列Bug修复PyCharm控制台pip install报错】如何解决pip安装报错ModuleNotFoundError: No module named ‘seaborn’问题 一、摘要 在使用 PyCharm 终端进行模块安装时&#xff0c;常常会遇到如下异常&#xff1a; ModuleNotFoundError: No module named ‘seaborn’…

(思维)洛谷 P13551 ももいろの鍵 题解

题意 爱莉给了你一个非负整数 nnn&#xff0c;你需要把 0,1,2,…,n0, 1, 2, \dots, n0,1,2,…,n 划分成若干组&#xff0c;满足每一组的按位与为 000。 划分的组不需要相邻。 你需要最大化划分组数并给出方案。 1≤T≤6001 \le T \le 6001≤T≤600&#xff0c;0≤n≤1050 \le n…