ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【ZJSU - 大红大紫:ACM - Template】比赛用模板10:博弈论

2022-09-10 13:02:42  阅读:260  来源: 互联网

标签:10 游戏 大红大紫 tt 石子 ZJSU pmb 获胜 SG


博弈论

巴什博奕

问题模板:

有 \(N\) 个石子,两名玩家轮流行动,按以下规则取石子:

规定:每人每次可以取走 \(X(1 \le X \le M)\) 个石子,拿到最后一颗石子的一方获胜。

双方均采用最优策略,询问谁会获胜。

两名玩家轮流报数。

规定:第一个报数的人可以报 \(X(1 \le X \le M)\) ,后报数的人需要比前者所报数大 \(Y(1 \le Y \le M)\) ,率先报到 \(N\) 的人获胜。

双方均采用最优策略,询问谁会获胜。

结论:

  • \(N=K*(M+1)\) (其中 \(K \in \mathbb{N}^+\) ),后手必胜(后手可以控制每一回合结束时双方恰好取走 \(M+1\) 个,重复 \(K\) 轮后即胜利);
  • \(N=K*(M+1)+R\) (其中 \(K \in \mathbb{N}^+,0 < R < M + 1\) ),先手必胜(先手先取走 \(R\) 个,之后控制每一回合结束时双方恰好取走 \(M+1\) 个,重复 \(K\) 轮后即胜利)。

扩展巴什博弈

问题模板

有 \(N\) 颗石子,两名玩家轮流行动,按以下规则取石子:。

规定:每人每次可以取走 \(X(a \le X \le b)\) 个石子,如果最后剩余物品的数量小于 \(a\) 个,则不能再取,拿到最后一颗石子的一方获胜。

双方均采用最优策略,询问谁会获胜。

结论

  • \(N = K*(a+b)\) 时,后手必胜;
  • \(N = K*(a+b)+R_1\) (其中 \(K \in \mathbb{N}^+,0 < R_1 < a\) ) 时,后手必胜(这些数量不够再取一次,先手无法逆转局面);
  • \(N = K*(a+b)+R_2\) (其中 \(K \in \mathbb{N}^+,a \le R_2 \le b\) ) 时,先手必胜;
  • \(N = K*(a+b)+R_3\) (其中 \(K \in \mathbb{N}^+,b < R_3 < a + b\) ) 时,先手必胜(这些数量不够再取一次,后手无法逆转局面);

\(\tt{}NIM\) 博弈

问题模板

有 \(N\) 堆石子,给出每一堆的石子数量,两名玩家轮流行动,按以下规则取石子:

规定:每人每次任选一堆,取走正整数颗石子,拿到最后一颗石子的一方获胜(注:几个特点是不能跨堆不能不拿)。

双方均采用最优策略,询问谁会获胜。

结论

记初始时各堆石子的数量 \((A_1,A_2, … ,A_n)\) ,定义尼姆和 \(Sum_N = A_1 \bigoplus A_2 \bigoplus … \bigoplus A_n\) 。

\(\pmb{ Sum_N = 0 }\) 时先手必败,反之先手必胜。


尼姆游戏具体取法

结论如下:

先计算出尼姆和,再对每一堆石子计算 \(A_i \bigoplus Sum_N\) ,记为 \(X_i\) 。

若得到的值 \(X_i<A_i\) ,\(X_i\) 即为一个可行解,即剩下 \(\pmb X_i\) 颗石头,取走 \(\pmb {A_i - X_i}\) 颗石头(这里取小于号是因为至少要取走 \(1\) 颗石子)。


\(\tt{} Moore’s\ Nim\) 游戏(\(\tt{}Nim - K\) 游戏)

问题模板

有 \(N\) 堆石子,给出每一堆的石子数量,两名玩家轮流行动,按以下规则取石子:

规定:每人每次任选不超过 \(K\) 堆,对每堆都取走不同的正整数颗石子,拿到最后一颗石子的一方获胜。

双方均采用最优策略,询问谁会获胜。

结论

把每一堆石子的石子数用二进制表示,定义 \(One_i\) 为二进制第 \(i\) 位上 \(1\) 的个数。

以下局面先手必胜:

对于每一位, \(\pmb{One_1,One_2,… ,One_N}\) 均不为 \(\pmb{K+1}\) 的倍数。


\(\tt{}Anti-Nim\) 游戏(反 \(\tt{}Nim\) 游戏)

问题模板

有 \(N\) 堆石子,给出每一堆的石子数量,两名玩家轮流行动,按以下规则取石子:

规定:每人每次任选一堆,取走正整数颗石子,拿到最后一颗石子的一方出局

双方均采用最优策略,询问谁会获胜。

结论

  • 所有堆的石头数量均不超过 \(1\) ,且 \(\pmb {Sum_N=0}\) (也可看作“且有偶数堆”);
  • 至少有一堆的石头数量大于 \(1\) ,且 \(\pmb{Sum_N \neq 0}\) 。

阶梯 - \(\tt{}NIM\) 博弈

模板

有 \(N\) 级台阶,每一级台阶上均有一定数量的石子,给出每一级石子的数量,两名玩家轮流行动,按以下规则操作石子:

规定:每人每次任选一级台阶,拿走正整数颗石子放到下一级台阶中,已经拿到地面上的石子不能再拿,拿到最后一颗石子的一方获胜。

双方均采用最优策略,询问谁会获胜。

结论

对奇数台阶做传统 \(\pmb{\tt{}Nim}\) 博弈,当 \(\pmb{Sum_N=0}\)** 时先手必败,反之先手必胜。**


\(\tt SG\) 游戏(有向图游戏)

我们使用以下几条规则来定义暴力求解的过程:

  • 使用数字来表示输赢情况,\(0\) 代表局面必败,非 \(0\) 代表存在必胜可能,我们称这个数字为这个局面的SG值;
  • 找到最终态,根据题意人为定义最终态的输赢情况;
  • 对于非最终态的某个节点,其SG值为所有子节点的SG值取 \(\tt{}mex\) ;
  • 单个游戏的输赢态即对应根节点的SG值是否为 \(0\) ,为 \(0\) 代表先手必败,非 \(0\) 代表先手必胜;
  • 多个游戏的总SG值为单个游戏SG值的异或和。

使用哈希表,以 \(\mathcal{O} (N + M)\) 的复杂度计算。

int n, m, a[N], num[N];
int sg(int x) {
    if (num[x] != -1) return num[x];
    
    unordered_set<int> S;
    for (int i = 1; i <= m; ++ i) 
        if(x >= a[i]) 
            S.insert(sg(x - a[i]));
    
    for (int i = 0; ; ++ i)
        if (S.count(i) == 0)
            return num[x] = i;
}
void Solve() {
    cin >> m;
    for (int i = 1; i <= m; ++ i) cin >> a[i];
    cin >> n;
    
    int ans = 0; memset(num, -1, sizeof num);
    for (int i = 1; i <= n; ++ i) {
        int x; cin >> x;
        ans ^= sg(x);
    }
    
    if (ans == 0) no;
    else yes;
}

\(\tt Anti-SG\) 游戏(反 \(\tt SG\) 游戏)

\(\tt SG\) 游戏中最先不能行动的一方获胜。

结论

以下局面先手必胜:

  • 单局游戏的SG值均不超过 \(\pmb 1\) ,且总SG值为 \(\pmb 0\);
  • 至少有一局单局游戏的SG值大于 \(\pmb 1\) ,且总SG值不为 \(\pmb 0\) 。

在本质上,这与 \(\tt Anti-Nim\) 游戏的结论一致。


\(\tt{}Lasker’s-Nim\) 游戏(\(\tt Multi-SG\) 游戏)

模板

有 \(N\) 堆石子,给出每一堆的石子数量,两名玩家轮流行动,每人每次任选以下规定的一种操作石子:

  • 任选一堆,取走正整数颗石子;
  • 任选数量大于 \(2\) 的一堆,分成两堆非空石子。

拿到最后一颗石子的一方获胜。双方均采用最优策略,询问谁会获胜。

结论

本题使用SG函数求解,SG值定义为:

\[\pmb{ SG(x) = \begin{cases} x-1 & \text{ , } x\mod 4= 0\\ x & \text{ , } x \mod 4 = 1\\ x & \text{ , } x \mod 4 = 2\\ x+1 & \text{ , } x \mod 4 = 3 \end{cases}}\]


\(\tt{}Every-SG\) 游戏

模板

给出一个有向无环图,其中 \(K\) 个顶点上放置了石子,两名玩家轮流行动,按以下规则操作石子:

移动图上所有还能够移动的石子;

无法移动石子的一方出局。双方均采用最优策略,询问谁会获胜。

结论

定义 \(step\) 为某一局游戏至多需要经过的回合数。

以下局面先手必胜:\(\pmb{step}\) 为奇数


威佐夫博弈

模板

有两堆石子,给出每一堆的石子数量,两名玩家轮流行动,每人每次任选以下规定的一种操作石子:

  • 任选一堆,取走正整数颗石子;
  • 从两队中同时取走正整数颗石子。

拿到最后一颗石子的一方获胜。双方均采用最优策略,询问谁会获胜。

结论

以下局面先手必败:

\(\pmb{ (1, 2), (3, 5), (4, 7), (6, 10), …}\) 具体而言,每一对的第一个数为此前没出现过的最小整数,第二个数为第一个数加上 \(\pmb{1,2,3,4,…}\) 。

更一般地,对于第 \(\pmb k\) 对数,第一个数为 \(\pmb {First_k= \left \lfloor \frac{k*(1+\sqrt 5)}{2} \right \rfloor}\) ,第二个数为 \(\pmb{Second_k=First_k+k}\) 。

其中,在两堆石子的数量均大于 \(10^9\) 次时,由于需要使用高精度计算,我们需要人为定义 \(\frac{1+\sqrt 5}{2}\) 的取值为 \(lorry = 1.618033988749894848204586834\) 。

const double lorry = (sqrt(5.0) + 1.0) / 2.0;
//const double lorry = 1.618033988749894848204586834;
void Solve() {
    int n, m; cin >> n >> m;
    if (n < m) swap(n, m);
    double x = n - m;
    if ((int)(lorry * x) == m) cout << "lose\n";
    else cout << "win\n";
}

斐波那契博弈

模板

有一堆石子,数量为 \(N\) ,两名玩家轮流行动,按以下规则取石子:

先手第1次可以取任意多颗,但不能全部取完,此后每人取的石子数不能超过上个人的两倍,拿到最后一颗石子的一方获胜。

双方均采用最优策略,询问谁会获胜。

结论

当且仅当 \(N\) 为斐波那契数时先手必败。

int fib[100] = {1, 2};
map<int, bool> mp;
void Force() {
  for (int i = 2; i <= 86; ++ i) fib[i] = fib[i - 1] + fib[i - 2];
    for (int i = 0; i <= 86; ++ i) mp[fib[i]] = 1;
}
void Solve() {
    int n; cin >> n;
    if (mp[n] == 1) cout << "lose\n";
    else cout << "win\n";
}

树上删边游戏

模板

给出一棵 \(N\) 个节点的有根树,两名玩家轮流行动,按以下规则操作:

选择任意一棵子树并删除(删去任意一条边,不与根相连的部分会同步被删去);

删掉最后一棵子树的一方获胜。双方均采用最优策略,询问谁会获胜。

结论

相较于传统SG值的定义,本题的SG函数值定义为:

  • 叶子节点的SG值为 \(\pmb 0\) 。
  • 非叶子节点的SG值为其所有孩子节点SG值 \(\pmb + 1\) 的异或和。

标签:10,游戏,大红大紫,tt,石子,ZJSU,pmb,获胜,SG
来源: https://www.cnblogs.com/WIDA/p/16676294.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有