Skip to content

Commit aa4dedb

Browse files
committed
✨feat: Add 2029
1 parent 665d24b commit aa4dedb

File tree

2 files changed

+119
-0
lines changed

2 files changed

+119
-0
lines changed

Index/博弈论.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
| [292. Nim 游戏](https://leetcode-cn.com/problems/nim-game/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/nim-game/solution/gong-shui-san-xie-noxiang-xin-ke-xue-xi-wmz2t/) | 中等 | 🤩🤩🤩🤩 |
44
| [810. 黑板异或游戏](https://leetcode-cn.com/problems/chalkboard-xor-game/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/chalkboard-xor-game/solution/gong-shui-san-xie-noxiang-xin-ke-xue-xi-ges7k/) | 困难 | 🤩🤩🤩🤩 |
55
| [877. 石子游戏](https://leetcode-cn.com/problems/stone-game/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/stone-game/solution/gong-shui-san-xie-jing-dian-qu-jian-dp-j-wn31/) | 中等 | 🤩🤩🤩🤩 |
6+
| [2029. 石子游戏 IX](https://leetcode-cn.com/problems/stone-game-ix/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/stone-game-ix/solution/gong-shui-san-xie-fen-qing-kuang-tao-lun-h1oa/) | 中等 | 🤩🤩🤩🤩 |
67

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
### 题目描述
2+
3+
这是 LeetCode 上的 **[2029. 石子游戏 IX](https://leetcode-cn.com/problems/stone-game-ix/solution/gong-shui-san-xie-fen-qing-kuang-tao-lun-h1oa/)** ,难度为 **中等**
4+
5+
Tag : 「博弈论」
6+
7+
8+
9+
`Alice``Bob` 轮流进行自己的回合,`Alice` 先手。每一回合,玩家需要从 `stones` 中移除任一石子。
10+
11+
如果玩家移除石子后,导致 所有已移除石子 的价值 总和 可以被 $3$ 整除,那么该玩家就 输掉游戏 。
12+
如果不满足上一条,且移除后没有任何剩余的石子,那么 `Bob` 将会直接获胜(即便是在 `Alice` 的回合)。
13+
假设两位玩家均采用 最佳 决策。如果 `Alice` 获胜,返回 `true` ;如果 `Bob` 获胜,返回 `false`
14+
15+
示例 1:
16+
```
17+
输入:stones = [2,1]
18+
19+
输出:true
20+
21+
解释:游戏进行如下:
22+
- 回合 1:Alice 可以移除任意一个石子。
23+
- 回合 2:Bob 移除剩下的石子。
24+
已移除的石子的值总和为 1 + 2 = 3 且可以被 3 整除。因此,Bob 输,Alice 获胜。
25+
```
26+
示例 2:
27+
```
28+
输入:stones = [2]
29+
30+
输出:false
31+
32+
解释:Alice 会移除唯一一个石子,已移除石子的值总和为 2 。
33+
由于所有石子都已移除,且值总和无法被 3 整除,Bob 获胜。
34+
```
35+
示例 3:
36+
```
37+
输入:stones = [5,1,2,4,3]
38+
39+
输出:false
40+
41+
解释:Bob 总会获胜。其中一种可能的游戏进行方式如下:
42+
- 回合 1:Alice 可以移除值为 1 的第 2 个石子。已移除石子值总和为 1 。
43+
- 回合 2:Bob 可以移除值为 3 的第 5 个石子。已移除石子值总和为 = 1 + 3 = 4 。
44+
- 回合 3:Alices 可以移除值为 4 的第 4 个石子。已移除石子值总和为 = 1 + 3 + 4 = 8 。
45+
- 回合 4:Bob 可以移除值为 2 的第 3 个石子。已移除石子值总和为 = 1 + 3 + 4 + 2 = 10.
46+
- 回合 5:Alice 可以移除值为 5 的第 1 个石子。已移除石子值总和为 = 1 + 3 + 4 + 2 + 5 = 15.
47+
Alice 输掉游戏,因为已移除石子值总和(15)可以被 3 整除,Bob 获胜。
48+
```
49+
50+
提示:
51+
* $1 <= stones.length <= 10^5$
52+
* $1 <= stones[i] <= 10^4$
53+
54+
---
55+
56+
### 分情况讨论博弈
57+
58+
为了方便,我们用 `A` 来代指 `Alice`,用 `B` 带代指 `Bob`
59+
60+
`A` 只有一种获胜方式,是使得 `B` 在选石子时凑成 $3$ 的倍数;而 `B` 除了能够通过让 `A` 凑成 $3$ 的倍数以外,还能通过让游戏常规结束来获胜。
61+
62+
因此整个游戏过程,我们只需要关心「已被移除的石子总和」和「剩余石子个数/价值情况」即可。
63+
64+
更进一步的,我们只需关心已被移除的石子总和是否为 $3$ 的倍数,以及剩余石子的价值与已移除石子总和相加是否凑成 $3$ 的倍数即可。
65+
66+
所以我们可以按照石子价值除以 $3$ 的余数分成三类,并统计相应数量。
67+
68+
不失一般性考虑,某个回合开始前,已移除的石子总和状态为 $x$(共三种,分别为除以 $3$ 余数为 $0$、$1$ 和 $2$,其中当状态为 $0$,且非首个回合时,说明凑成 $3$ 的倍数,游戏结束),剩余石子价值除以 $3$ 的余数 $s$ 分别为 $0$、$1$ 和 $2$。
69+
70+
**首先如果当前 $x = 1$ 时,不能选择 $s = 2$ 的石子,否则会导致凑成总和为 $3$ 的倍数而失败;同理 $x = 2$ 时,不能选择 $s = 1$ 的石子;而选择 $s = 0$ 的数字,不会改变 $x$ 的状态,可看做换手操作。**
71+
72+
**同时成对的 $s = 0$ 的等价于没有 $s = 0$ 的石子(双方只需要轮流选完这些 $s = 0$ 的石子,最终会回到先手最开始的局面);而选择与 $x$ 相同的 $s$ 会导致 $x$ 改变(即 $x = 1$ 时,选择 $s = 1$ 的石子,会导致 $x = 2$;而 $x = 2$ 时,选 $s = 2$ 的石子,会导致 $x = 1$)。**
73+
74+
明确规则后,是分情况讨论的过程:
75+
76+
* **$s = 0$ 的石子数量为偶数**:此时等价于没有 $s = 0$ 的石子,我们只需要关心 $s = 1$ 和 $s = 2$ 即可:
77+
78+
* **$s = 1$ 的石子数量为 $0$**: 这意味着 `A` 开始选择的只能是 $s = 2$,此时交给 `B` 的局面为「$x = 2$、剩余石子只有 $s = 2$」,此时 `B` 只能选 $s = 2$ 的石子,由于 $x = 2$ 且选择的石子 $s = 2$,因此交由回 `A` 的局面为「$x = 1$,剩余是在只有 $s = 2$」,因此游戏继续的话 `A` 必败,同时如果在该过程的任何时刻石子被取完,也是 `B` 直接获胜,即 **`A` 仍为必败**
79+
80+
* **$s = 2$ 的石子数量为 $0$**:分析同理,`A` 只能选 $s = 1$,此时交给 `B` 的局面为「$x = 1$、剩余石子只有 $s = 1$」,此时 `B` 只能选 $s = 1$ 的石子,由于 $x = 1$ 且选择的石子 $s = 1$,因此交由回 `A` 的局面为「$x = 2$,剩余是在只有 $s = 1$」,因此游戏继续的话 `A` 必败,同时如果在该过程的任何时刻石子被取完,也是 `B` 直接获胜,即 **`A` 仍为必败**
81+
82+
* **$s = 1$ 和 $s = 2$ 的石子数量均不为 $0$**`A` 选数量不是最多的一类石子,`B` 下一回合只能选择相同类型的石子(或是无从选择导致失败),然后游戏继续,最终 `B` 会先进入「只能凑成 $3$ 的倍数」的局面导致失败,即 **`A` 必胜。**
83+
84+
* **$s = 0$ 的石子数量为奇数**:此时等价于有一次换手机会,该换手机会必然应用在「对必败局面进行转移」才有意义,因此只有 $s = 1$ 和 $s = 2$ 的石子数量差大于 $2$,`A` 的先手优势不会因为存在换手机会而被转移:
85+
86+
* **两者数量差不超过 $2$**:此时 `B` 可以利用「对方凑成 $3$ 的倍数必败」规则和「优先使用 $s = 0$ 石子」权利来进入确保自己为必胜态:
87+
88+
* 举个 🌰,当 $s = 1$ 和 $s = 2$ 的石子数量相等,虽然有 $s = 0$ 的石子,`A` 先手,但是 `A` 的首个回合必然不能选 $s = 0$,否则马上失败结束,因此 `A` 只能选 $s = 1$ 或 $s = 2$,此时 `B`直接选择 $s = 0$ 的石子,交由给 `A` 的局面 $x$ 没有发生改变,`A` 只能选择与首个回合相同的 $s$ 游戏才能继续,因此局面会变为「`B` 先手、$s = 1$ 和 $s = 2$ 的石子数量差为 $2$」,游戏继续,最终 `A` 会先遇到「只能凑成 $3$ 的倍数」的局面,即 **`B` 必胜**
89+
90+
* 两者数量差不超过 $2$:此时无论 `A` 选择数量较少或较多的 `s``B` 都在第二回合马上使用 $s = 0$ 的石子进行换手,`A` 只能继续选与第一回合相同类型的的石子,游戏才能进行,最终 `A` 会先遇到「只能凑成 $3$ 的倍数」或「石子被取完」的局面,即 **`B` 必胜**
91+
92+
* **两者数量差超过 $2$** :此时即使 `A` 只要确保第一次选择数量较多的 $s$,不管 `B` 是否使用「优先使用 $s = 0$」的石子,`A` 都有足够次数数量多 $s$ 来抵消换手(或是在 `B` 放弃使用 $s = 0$ 之后马上使用),最终都是 `B` 最先遇到「只能凑成 $3$ 的倍数」的局面,即 **`A` 获胜**
93+
94+
代码:
95+
```Java
96+
class Solution {
97+
public boolean stoneGameIX(int[] stones) {
98+
int[] cnts = new int[3];
99+
for (int i : stones) cnts[i % 3]++;
100+
return cnts[0] % 2 == 0 ? !(cnts[1] == 0 || cnts[2] == 0) : !(Math.abs(cnts[1] - cnts[2]) <= 2);
101+
}
102+
}
103+
```
104+
* 时间复杂度:$O(n)$
105+
* 空间复杂度:$O(1)$
106+
107+
---
108+
109+
### 最后
110+
111+
这是我们「刷穿 LeetCode」系列文章的第 `No.2029` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
112+
113+
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
114+
115+
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode
116+
117+
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。
118+

0 commit comments

Comments
 (0)