博弈论进阶——Anti-SG
博弈论进阶——-
博弈多年以后,仍然爱慕着的容颜
函数的拓展-游戏
感谢贾志豪《组合游戏略述——浅谈SG游戏的若干拓展及变形》一文
一、游戏
有堆石子,两个人可以从任意一堆石头中拿走任意颗石头,拿走最后一个石头的失败。
这与我们之前处理的游戏有所不同,即两人胜利的条件发生了改变,与游戏相反,所以被称之为反游戏。
结论:
先手必胜当且仅当满足下面两种情况的一种:
(1)任意堆的石子数都为且游戏的值为
(2)存在堆的石子数大于且游戏的值不为
证明:
假设有堆石子。
- 每堆只有一个石子
之前我们就证明过每一堆石子的值显然是这堆石子的个数。每一堆的石子数均为。
很容易看出:
当有偶数堆时,也就是值为时,先手必胜
当有奇数堆时,也就是值为时,先手必败 - 至少两堆石子数大于
考虑两种情况,当为和不为的情况。
- 当 不为 时
若还有至少两堆石子的数目大于 ,则先手将 值变为 即可;若只有一堆石子数大于 ,则先手总可以将状态变为有奇数个 。所以,当 不为 时先手必胜。 - 当 为 时
至少有两堆石子的数目大于 ,则先手决策完之后,必定至少有一堆的石子数大于 ,且 值不为 ,由上段的论证我们可以发现,此时,无论先手如何决策,都只会将游戏带入先手必胜局,所以先手必败。
(说实话感觉大佬贾志豪这段的证明有点问题)
另外一种证明方式
二、
游戏与游戏不同的点仅仅在于是最后一个进行操作的输。
函数存在这样一个性质:
为的局面不一定为终局局面。(定理一的反命题)
基于这个性质我们可以知道的结论并不能直接套用在上面。
对于这个问题,贾志豪给出了
定理
规定当局面中所有的单一游戏值为时,游戏结束,则先手必胜当且仅当
- 游戏值不为且游戏中某个单一游戏的函数大于
- 游戏函数为且游戏中没有单一游戏的函数大于
证明(全文照搬):
我们只需要证明:
- 所有的终止局面为先手必胜局。(这一点显然,证明中略去)
- 游戏中的任何一个先手必败局一定只能够转移到先手必胜局;
- 游戏中的任何一个先手必胜局一定能够转移到至少一个先手必败局。
情况一:局面的 SG 函数为 0 且游戏中某单一游戏的 SG 函数大于1。
∵当前局面的 SG 函数值为 0
又∵SG 函数性质
∴它所能转移到的任何一个局面的 SG 函数值不为 0 ①
∵当前局面的 SG 函数值为 0 且游戏中某个单一游戏的 SG 函数大于1。
∴当前局面中必定至少有 2 个单一游戏的 SG 函数大于 1。
又∵每次至多只能更改一个单一游戏的 SG 值
∴它所能转移到的任何一个局面都至少有一个单一游戏的 SG 值大于1。②
由①②得,情况一所能转移到的任何一个局面都为先手必胜局。
情况二:局面的 SG 函数不为 0 且游戏中没有单一游戏的 SG 函数大于 1。
显然,当前局面一定有奇数个游戏的 SG 函数值为 1,其余游戏的 SG函数值为 0。
- 将某个单一游戏的 SG 值更改为大于 1 的数。
∵转移前没有单一游戏的 SG 值大与 1,转移将某个单一游戏的 SG值更改为大于 1 的数。
∴转移后的局面一定有且只有一个单一游戏的 SG 值大于 1。 ③
∴后继局面的 SG 值一定不为 0。 ④
由③④得,后继局面一定为先手必胜局。 - 将某个单一游戏的 SG 值更改为 0 或 1。
∵转移是将某个 SG 值为 0 的单一游戏改成 SG 值为 1 的单一游戏,或将某个 SG 值为 1 的单一游戏改成 SG 值为 0 的单一游戏。
∴转移后的局面一定有偶数个 SG 值为 1 的单一局面且不含有 SG 值大于 1 的局面。
∴后继局面一定为先手必胜局。
情况三:局面的 SG 函数不为 0 且游戏中某个单一游戏的 SG 函数大于 1
- 局面中只有 1 个单一游戏的 SG 值大于 1。
我们选择更改 SG 值最大的单一游戏,我们可以选择将其更改成 0 或1 来保证转移后的局面有且只有奇数个 SG 值为 1 的单一游戏。
则通过这种方式转以后的局面为先手必败局。 - 局面中有至少两个单一游戏的 SG 值大于 1。
根据 SG 函数性质(2),总存在一种决策可以将后继局面的 SG 函数值变为 0 ⑤
∵局面中有至少两个单一游戏的 SG 值大于 1
又∵每次最多只能更改一个单一游戏的 SG 值
∴后继局面中至少有一个游戏的 SG 值大于 1 ⑥
由⑤⑥得,后继局面为先手必败局。
情况四:局面的 SG 函数为 0 且游戏中没有单一游戏的 SG 函数大于1。
当局面中所有单一游戏的 SG 值为 0 时,游戏结束,先手必胜。
否则,局面有且仅有偶数个 SG 值为 1 的单一游戏,其余游戏的 SG
值为 0。
我们只需将其中的某一个 SG 值为 1 的单一游戏的 SG 值变为 0,游戏中即可出现奇数个 SG 值为 1 的单一游戏,到达先手必败局。
实际上,聪明的读者可能会发现,我们在 SJ 定理中给出的附加条件“规定当局面中所有的单一游戏的 SG 值为 0 时,游戏结束”过于严格,完全可以替换成“当局面中所有的单一游戏的 SG 值为 0 时,存在一个单
一游戏它的 SG 函数能通过一次操作变为 1”。
笔者为什么要将限制条件设制成这样?
因为笔者发现这样可以出题,我们可以将题目模型设成这样:游戏
中存在一个按钮,游戏双方都可以触动按钮,当其中一个人触动按钮时,
触动按钮的人每次必须移动对方上次移动的棋子。如果触动按钮的人能
保证他能够使得对方无路可走,那么他同样获胜!
一道模板题
code
#include <bitset>
#include <vector>
#include <iostream>
#include <cstring>
#include <cmath>
#include <queue>
#include <algorithm>
#include <map>
#include <unordered_map>
using namespace std;
using namespace std;
#define lowbit(x) x&-x
#define ll int
#define pll pair<ll,ll>
#define dob double
#define For(i,s,n) for(ll i = s;i <= n;i++)
#define mem0(a) memset(a,0,sizeof a)
#define gcd(a,b) __gcd(a,b)
#define lcm(a,b) a/gcd(a,b)*b
#define abs(x) x>=0?x:-x
const int N = 1e5+5;
const double eps = 1e-6;
const ll mod = 1000000007;
const ll inf = 1e9+50;
int main(){
ios::sync_with_stdio(false);
ll t;cin>>t;
while(t--){
ll n;cin>>n;
ll sum = 0,cnt = 0;
for(ll i = 1;i <= n;i++){
ll x;cin>>x;
if(x>1)cnt++;
sum^=x;
}
if((sum == 0 && cnt == 0)||(sum && cnt)) cout<<"John\n";
else cout<<"Brother\n";
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具