From 08c804bb361ae3bc26ff55cc9c79c69940f4ae35 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=84=E6=B5=B7?= <10402852@qq.com>
Date: Mon, 25 Dec 2023 07:48:44 +0800
Subject: [PATCH 01/87] 'commit'
---
TangDou/AcWing/Math/QiWang/217.drawio | 1 -
TangDou/AcWing/Math/QiWang/217.md | 206 ------------------
TangDou/AcWing/Math/QiWang/217_DaoTui.cpp | 44 ----
TangDou/AcWing/Math/QiWang/217_ZhengTui.cpp | 59 -----
TangDou/AcWing/Math/QiWang/218.md | 152 -------------
TangDou/AcWing/Math/QiWang/218_dp.cpp | 48 ----
.../T5/QiWang/218.cpp} | 0
TangDou/AcWing_TiGao/T5/QiWang/218_dfs.cpp | 70 ------
TangDou/AcWing_TiGao/T5/QiWang/218_dp.cpp | 48 ----
9 files changed, 628 deletions(-)
delete mode 100644 TangDou/AcWing/Math/QiWang/217.drawio
delete mode 100644 TangDou/AcWing/Math/QiWang/217.md
delete mode 100644 TangDou/AcWing/Math/QiWang/217_DaoTui.cpp
delete mode 100644 TangDou/AcWing/Math/QiWang/217_ZhengTui.cpp
delete mode 100644 TangDou/AcWing/Math/QiWang/218.md
delete mode 100644 TangDou/AcWing/Math/QiWang/218_dp.cpp
rename TangDou/{AcWing/Math/QiWang/218_dfs.cpp => AcWing_TiGao/T5/QiWang/218.cpp} (100%)
delete mode 100644 TangDou/AcWing_TiGao/T5/QiWang/218_dfs.cpp
delete mode 100644 TangDou/AcWing_TiGao/T5/QiWang/218_dp.cpp
diff --git a/TangDou/AcWing/Math/QiWang/217.drawio b/TangDou/AcWing/Math/QiWang/217.drawio
deleted file mode 100644
index d9a22c8..0000000
--- a/TangDou/AcWing/Math/QiWang/217.drawio
+++ /dev/null
@@ -1 +0,0 @@
-5VpLc9owEP41zLSHMtbLj2NDHj00M+mkbdLePFiAEmNRI4rJr6+MZbAlB0gCVgkzHLwraWV9+3m1WtFBvXF2lYaT0TWPaNyBTpR10HkHQoAh7OQ/J1oUGt8jhWKYskh1Witu2RNVSkdpZyyi01pHwXks2KSu7PMkoX1R04Vpyuf1bgMe12edhENqKG77YWxq71gkRkrrErxu+ELZcFRODdygaBmHZW+1lOkojPi8okIXHdRLORfF0zjr0ThHrwSmGHf5TOvqzVKaiF0GDB7cy3F2+fPp4QpP/izI7Ovi/pOy8jeMZ2rFD+ptxaLEQJqRcEvhbD5igt5Own7eMpcel7qRGMdSAvIxnE4KHwxYRuWsZ1OR8scVcFhqBjwRyssQlbKaqmFF5evRVNCsolIrvKJ8TEW6kF1Ua4AV2opvIFDyfO09olSjit9KXaj4MlxZXiMqHxSozQBf9JxfT78ZFL9/XH0PxfUw/PatAeAM2EbYgLMB9GcRdoM6wtCxjDA0EUZHjbDneTWEEbKMMDIRhkeNcKBxGNvmMDYRfjxqhH2/jjCxzWFiIJwcNcAu1AC2TWHXANjEN4k+5zmZlPpxOJ2yfh3WlM+SKMfz3NEQ9KRMMybuVVv+/Ct/7hIlnWeVpvNFKSRyaffK/FKojMrF9bClVI4z/VkshkZGumgkK1M+S/t0e84lwnRIxbbUwSTAjg5OaRwK9rf+uk1eVzPccCYXst6EHC1EehpximWqUdW0UzdENENQM1TgYBhaknC17Nfz0jN4edeQgckPUdTJWFCgx2OeSk3CkzwuDFgca6owZsMkZ7TkAZX6s/yzZvIE8Vk1jFkUxc8Flc2U30cg1uIE8M044TbQCB0qTvitxYku9CuhArwmULw4TORGb2jKJFY5GZa9LIQOaDN0BNoXLw3vJ3RApBk6cOgI2qMq2Zmp/8XWhK3yy8V1Wug5za788n3YdT3PdQMijWpWEfa6aHn4klsfQq7jtsq9sgB2ePKBN1BvFTYrKdUugdMCZZFVypZlz7dSNgBBTlnfgW7g5QyumSXY6WIMCCI+CggO2mWsWeo6VLh8wQlgA2e1MwHcwtmltJ+9fVOVZSuRiVUiBxtCpsztq40owK8jOXBg/XPBoN0zAzBrinum8u603HZU3SMD8TEwEDj6yVTPCnelmavXqFo+mQKzrnqogPmC/PK1W/q+8tJNtyj/NzNPIy81S9Ut7PJvyEs9WI+nEi+7+zw8Bi6/oyhrVv7vGi4IT6YACD3LBUBg3hTcNdwnvluHGJ8Wari6adcjTTVy8/7x3XrE9zSHNPxppF2HmEXywYcMfDwdl7hAcwm27RKzGCxdgk7IJZ7216rVRZ4tl5Tz110CT8gl+t6Obe/t0KwBSpc8npBL9DsrQg7mEimu/z1apMvrP+Gii38=
\ No newline at end of file
diff --git a/TangDou/AcWing/Math/QiWang/217.md b/TangDou/AcWing/Math/QiWang/217.md
deleted file mode 100644
index 83cfec7..0000000
--- a/TangDou/AcWing/Math/QiWang/217.md
+++ /dev/null
@@ -1,206 +0,0 @@
-##[$AcWing$ $217$. 绿豆蛙的归宿](https://www.acwing.com/problem/content/description/219/)
-
-### 一、题目描述
-给出一个有向无环的连通图,起点为 $1$ ,终点为 $N$,每条边都有一个长度。
-
-数据保证从起点出发能够到达图中所有的点,图中所有的点也都能够到达终点。
-
-绿豆蛙从起点出发,走向终点。
-
-到达每一个顶点时,如果有 $K$ 条离开该点的道路,绿豆蛙可以选择任意一条道路离开该点,并且走向每条路的概率为 $1/K$。
-
-现在绿豆蛙想知道,从起点走到终点所经过的路径总长度的 **期望** 是多少?
-
-**输入格式**
-第一行: 两个整数 $N,M$,代表图中有 $N$ 个点、$M$ 条边。
-
-第二行到第 $1+M$ 行: 每行 $3$ 个整数 $a,b,c$,代表从 $a$ 到 $b$ 有一条长度为 $c$ 的有向边。
-
-**输出格式**
-输出从起点到终点路径总长度的 **期望值**,结果四舍五入保留两位小数。
-
-**数据范围**
-$1≤N≤10^5,1≤M≤2N$
-
-**输入样例:**
-```cpp {.line-numbers}
-4 4
-1 2 1
-1 3 2
-2 3 3
-3 4 4
-```
-
-**输出样例:**
-```cpp {.line-numbers}
-7.00
-```
-
-### 二、数学期望
-
-**[视频讲解 数学期望及性质](https://www.ixigua.com/6978816201023554061)**
-
-**[参考题解](https://www.acwing.com/solution/content/63508/)**
-
-首先明白一点:到达某个结果的期望值 = 这个结果 * 从起始状态到这个状态的概率
-
-$Q:$什么意思呢?
-
-如图:
-
-
-我们计算从$1$号点到$3$号点的期望距离
-
-路径$1$. $\displaystyle 1−>3:E_1=2×\frac{1}{2}=1$
-
-路径$2$. $\displaystyle 1−>2−>3:E_2=1×\frac{1}{2}+3×\frac{1}{2}×1=2$
-
-这里路径$2$中从$1$到$2$概率为$\displaystyle \frac{1}{2}$,但单看从$2$到$3$概率就是$1$,但是从$1$到$3$那就是从($1$到$2$的概率)$\displaystyle \frac{1}{2}$×$1$($2$到$3$的概率)=$\displaystyle \frac{1}{2}$。
-
-所以从 点$1$ 到 点$3$ 的数学期望值=$1+2=3$
-
-总结:概率是叠乘的
-
-
-本题有 **正推** 和 **倒推** 两种写法:
-
-### 二、正推法
-
-
-设:
-- $a_1, a_2, a_3 … a_k$ 到 $j$ 的权值为 $w_1, w_2, w_3 … w_k$,
-- 从起点到这$k$个点的概率为:$p_1, p_2, p_3 … p_k$
-- 每个点的出度为:$out_1, out_2, out_3, … , out_k$
-
-这里的$1\sim k$个点的从起点的到该点的概率一定是确定的,也就是说这个点的概率是被更新完的,即此时这个点的入度为$0$!
-
-那么就有:
-$$f(i):表示从起点到i点的期望距离$$
-$$f(j)=\frac{f(1)+w_1\times p_1}{out_1}+\frac{f(2)+w_2\times p_2}{out_2}+\frac{f(3)+w_3\times p_3}{out_3}+...+\frac{f(k)+w_k\times p_k}{out_k} $$
-
-#### 正推代码
-```cpp {.line-numbers}
-#include
-using namespace std;
-const int N = 1e5 + 10, M = 2 * N;
-
-//邻接表
-int h[N], e[M], ne[M], w[M], idx;
-void add(int a, int b, int c) {
- e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
-}
-
-int n, m; // n个顶点,m条边
-
-int out[N], in[N]; //出度,入度
-double f[N], g[N]; // f:数学期望结果 g:概率
-
-void topsort() {
- queue q;
- //起点为1,起点的概率为100%
- q.push(1);
- g[1] = 1.0;
- f[1] = 0.0;
-
- // DAG,执行拓扑序,以保证计算的顺序正确,确保递归过程中,前序数据都已处理完毕
- while (q.size()) {
- auto u = q.front();
- q.pop();
-
- for (int i = h[u]; ~i; i = ne[i]) { //枚举的是每边相邻边
- int j = e[i]; //此边,一端是t,另一端是j
- //此边边条w[i]
- f[j] += (f[u] + w[i] * g[u]) / out[u];
- g[j] += g[u] / out[u]; // p[j]也需要概率累加
- //拓扑序的标准套路
- in[j]--;
- if (!in[j]) q.push(j);
- }
- }
-}
-
-int main() {
- //初始化邻接表
- memset(h, -1, sizeof h);
- cin >> n >> m;
-
- while (m--) {
- int a, b, c;
- cin >> a >> b >> c;
- add(a, b, c);
- //维护出度,入度
- out[a]++, in[b]++;
- }
- //拓扑序
- topsort();
-
- //正向递推,输出结果,保留两位小数
- printf("%.2lf", f[n]);
-
- return 0;
-}
-```
-### 三、倒推法
-现在学会了正推,来看看 **逆推**,即 **从终点找到起点**
-
-
-
-
-设 $f[x]$ 表示结点 $x$ 走到终点所经过的路径的期望长度。显然 $f[n]=0$ ,最后要求 $f[1]$ 。
-
-一般来说,**初始状态确定时可用顺推,终止状态确定时可用逆推**。
-
-设 $x$ 出发有 $k$ 条边,分别到达 $y_1,y_2...y_k$ ,边长分别为 $z_1,z_2...z_k$ ,根据数学期望的定义和性质,有:
-
-$$f[x]=\frac 1 k\times (f[y_1]+z_1)+\frac 1 k\times (f[y_2]+z_2)+...+\frac 1 k\times (f[y_k]+z_k)=\frac 1 k \times \sum_{i=1}^k(f[y_i]+z_i)$$
-根据设定已经确定是能够到达 $n$ 点了,概率为 $1$ 。
-
-$f[n]$ 已知,需要求解 $f[1]$ ,建立 **反向图**,按照 **拓扑序** 求解。
-
-#### 倒推代码
-```cpp {.line-numbers}
-#include
-using namespace std;
-const int N = 100010, M = N << 1;
-int n, m;
-int in[N], g[N]; //入度,入度的备份数组,原因:in在topsort中会不断变小受破坏
-
-double f[N];
-
-//链式前向星
-int e[M], h[N], idx, w[M], ne[M];
-void add(int a, int b, int c = 0) {
- e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
-}
-
-void topsort() {
- queue q;
- q.push(n);
- f[n] = 0; // n到n的距离期望是0
- while (q.size()) {
- int u = q.front();
- q.pop();
- for (int i = h[u]; ~i; i = ne[i]) { //枚举每条入边(因为是反向图)
- int j = e[i];
- f[j] += (f[u] + w[i]) / g[j];
- in[j]--;
- if (in[j] == 0) q.push(j);
- }
- }
-}
-int main() {
- memset(h, -1, sizeof(h));
- cin >> n >> m;
-
- while (m--) {
- int a, b, c;
- cin >> a >> b >> c;
- add(b, a, c); //反向图,计算从n到1
- in[a]++; //入度
- g[a] = in[a]; //入度数量
- }
- topsort();
- printf("%.2lf\n", f[1]);
- return 0;
-}
-```
\ No newline at end of file
diff --git a/TangDou/AcWing/Math/QiWang/217_DaoTui.cpp b/TangDou/AcWing/Math/QiWang/217_DaoTui.cpp
deleted file mode 100644
index ba0fe13..0000000
--- a/TangDou/AcWing/Math/QiWang/217_DaoTui.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-#include
-using namespace std;
-const int N = 100010, M = N << 1;
-int n, m;
-int in[N], g[N]; //入度,入度的备份数组,原因:in在topsort中会不断变小受破坏
-
-double f[N];
-
-//链式前向星
-int e[M], h[N], idx, w[M], ne[M];
-void add(int a, int b, int c = 0) {
- e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
-}
-
-void topsort() {
- queue q;
- q.push(n);
- f[n] = 0; // n到n的距离期望是0
- while (q.size()) {
- int u = q.front();
- q.pop();
- for (int i = h[u]; ~i; i = ne[i]) { //枚举每条入边(因为是反向图)
- int j = e[i];
- f[j] += (f[u] + w[i]) / g[j];
- in[j]--;
- if (in[j] == 0) q.push(j);
- }
- }
-}
-int main() {
- memset(h, -1, sizeof(h));
- cin >> n >> m;
-
- while (m--) {
- int a, b, c;
- cin >> a >> b >> c;
- add(b, a, c); //反向图,计算从n到1
- in[a]++; //入度
- g[a] = in[a]; //入度数量
- }
- topsort();
- printf("%.2lf\n", f[1]);
- return 0;
-}
\ No newline at end of file
diff --git a/TangDou/AcWing/Math/QiWang/217_ZhengTui.cpp b/TangDou/AcWing/Math/QiWang/217_ZhengTui.cpp
deleted file mode 100644
index 05e64ee..0000000
--- a/TangDou/AcWing/Math/QiWang/217_ZhengTui.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-#include
-using namespace std;
-const int N = 1e5 + 10, M = 2 * N;
-
-//邻接表
-int h[N], e[M], ne[M], w[M], idx;
-void add(int a, int b, int c) {
- e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
-}
-
-int n, m; // n个顶点,m条边
-
-int out[N], in[N]; //出度,入度
-double f[N], g[N]; // f:数学期望结果 g:概率
-
-void topsort() {
- queue q;
- //起点为1,起点的概率为100%
- q.push(1);
- g[1] = 1.0;
- f[1] = 0.0;
-
- // DAG,执行拓扑序,以保证计算的顺序正确,确保递归过程中,前序数据都已处理完毕
- while (q.size()) {
- auto u = q.front();
- q.pop();
-
- for (int i = h[u]; ~i; i = ne[i]) { //枚举的是每边相邻边
- int j = e[i]; //此边,一端是t,另一端是j
- //此边边条w[i]
- f[j] += (f[u] + w[i] * g[u]) / out[u];
- g[j] += g[u] / out[u]; // p[j]也需要概率累加
- //拓扑序的标准套路
- in[j]--;
- if (!in[j]) q.push(j);
- }
- }
-}
-
-int main() {
- //初始化邻接表
- memset(h, -1, sizeof h);
- cin >> n >> m;
-
- while (m--) {
- int a, b, c;
- cin >> a >> b >> c;
- add(a, b, c);
- //维护出度,入度
- out[a]++, in[b]++;
- }
- //拓扑序
- topsort();
-
- //正向递推,输出结果,保留两位小数
- printf("%.2lf", f[n]);
-
- return 0;
-}
\ No newline at end of file
diff --git a/TangDou/AcWing/Math/QiWang/218.md b/TangDou/AcWing/Math/QiWang/218.md
deleted file mode 100644
index a4c716a..0000000
--- a/TangDou/AcWing/Math/QiWang/218.md
+++ /dev/null
@@ -1,152 +0,0 @@
-##[$AcWing$ $218$. 扑克牌 ](https://www.acwing.com/problem/content/description/220/)
-
-### 一、题目描述
-$Admin$ 生日那天,$Rainbow$ 来找 $Admin$ 玩扑克牌。
-
-玩着玩着 $Rainbow$ 觉得太没意思了,于是决定给 $Admin$ 一个考验。
-
-$Rainbow$ 把一副扑克牌($54$张)随机洗开,倒扣着放成一摞。
-
-然后 $Admin$ 从上往下依次翻开每张牌,每翻开一张黑桃、红桃、梅花或者方块,就把它放到对应花色的堆里去。
-
-$Rainbow$ 想问问 $Admin$,得到 $A$ 张黑桃、$B$ 张红桃、$C$ 张梅花、$D$ 张方块需要翻开的牌的张数的期望值 $E$ 是多少?
-
-特殊地,如果翻开的牌是大王或者小王,$Admin$ 将会把它作为某种花色的牌放入对应堆中,使得放入之后 $E$的值尽可能小。
-
-由于 $Admin$ 和 $Rainbow$ 还在玩扑克,所以这个程序就交给你来写了。
-
-**输入格式**
-输入仅由一行,包含四个用空格隔开的整数,$A,B,C,D$。
-
-**输出格式**
-输出需要翻开的牌数的期望值 $E$,四舍五入保留 $3$ 位小数。
-
-如果不可能达到输入的状态,输出 `-1.000`。
-
-**数据范围**
-$0≤A,B,C,D≤15$
-
-**输入样例:**
-```cpp {.line-numbers}
-1 2 3 4
-```
-
-**输出样例:**
-```cpp {.line-numbers}
-16.393
-```
-
-### 二、题意分析
-
-$Q$:为什么从终止状态向起始状态递推?
-
-**答**:满足条件的终止状态较多,而起始状态唯一。考虑以终止状态为初值,起始状态为目标,进行动态规划。
-
-#### 状态表示
-$f[a][b][c][d][x][y]$ : 当前已翻开状态下,还需翻开牌的数量 **期望数**。
-
-- $a,b,c,d$ 为已翻开的各类牌 (黑红花片) 的数量
-- $x,y$代表大、小王的状态($0$为未翻开,$1$代表已翻开且当做黑桃,以此类推), 设 $rst$ 为剩余牌的数量。
-$$rst=54-a-b-c-d-(x!=0)-(y!=0)$$
-
-若 $a < 13$,则当前抽到黑桃的贡献为
-
-$$\frac{13−a}{rst} \times f[a+1][b][c][d][x][y]$$
-
-其余花色同理。若小王被抽取,取可转移状态期望最小的一个进行状态转移,其贡献为:
-
-$$\frac{1}{rst} \times \min_{1≤i≤4}f[a][b][c][d][i][y]$$
-
-大王同理。
-
-记忆化搜索求解,若无牌可抽仍未到达 $a > = A \&\& b > = B \&\& c > = C \&\& d > = D$ 的终止状态,则期望为正无穷,代表不合法的状态。
-
-
-#### 三、实现代码
-
-```cpp {.line-numbers}
-#include
-using namespace std;
-const int N = 15;
-const int INF = 0x3f3f3f3f;
-double f[N][N][N][N][5][5];
-int st[N][N][N][N][5][5];
-int A, B, C, D;
-
-//如果大小王翻出来放1里,则a++,放2里b++,...
-void add(int &a, int &b, int &c, int &d, int x) {
- if (x == 1) a++;
- if (x == 2) b++;
- if (x == 3) c++;
- if (x == 4) d++;
-}
-
-/*
-功能:计算当前状态f(a,b,c,d,x,y)下的期望值
-*/
-double dfs(int a, int b, int c, int d, int x, int y) {
- //记忆化,同时因为f为double类型,不能使用传统的memset(0x3f)之类
- //进行初始化并判断是否修改过,只能再开一个st数组
- if (st[a][b][c][d][x][y]) return f[a][b][c][d][x][y];
- st[a][b][c][d][x][y] = 1;
-
- //递归出口:当前状态是否到达目标状态,目标状态的期望值是0
- int ta = a, tb = b, tc = c, td = d; //抄出来
- add(ta, tb, tc, td, x), add(ta, tb, tc, td, y); //大王小王会改变四个花色的数量
- if (ta >= A && tb >= B && tc >= C && td >= D) return 0;
-
- //当前状态下的剩余牌数量
- int rst = 54 - ta - tb - tc - td;
- if (rst == 0) return INF; //还没有完成目标,没有剩余的牌了,无解
-
- //当前状态可以向哪些状态转移
- // Q:v为什么要初始化为1?
- // A:看题解内容
- double v = 1;
- if (a < 13) //黑桃有剩余,可能选出的是黑桃
- v += dfs(a + 1, b, c, d, x, y) * (13 - a) / rst;
- if (b < 13) //红桃有剩余,可能选出的是红桃
- v += dfs(a, b + 1, c, d, x, y) * (13 - b) / rst;
- if (c < 13) //梅花有剩余,可能选出的是梅花
- v += dfs(a, b, c + 1, d, x, y) * (13 - c) / rst;
- if (d < 13) //方块有剩余,可能选出的是方块
- v += dfs(a, b, c, d + 1, x, y) * (13 - d) / rst;
-
- //如果小王没有被选出
- if (x == 0)
- v += min(min(dfs(a, b, c, d, 1, y), dfs(a, b, c, d, 2, y)), min(dfs(a, b, c, d, 3, y), dfs(a, b, c, d, 4, y))) / rst;
-
- //如果大王没有被选出
- if (y == 0)
- v += min(min(dfs(a, b, c, d, x, 1), dfs(a, b, c, d, x, 2)), min(dfs(a, b, c, d, x, 3), dfs(a, b, c, d, x, 4))) / rst;
-
- return f[a][b][c][d][x][y] = v;
-}
-
-int main() {
- cin >> A >> B >> C >> D;
- //① 终点状态不唯一,起点是唯的的,所以以起点为终点,以终点为起点,反着推
- //② AcWing 217. 绿豆蛙的归宿 需要建图,本题不用建图
- double res = dfs(0, 0, 0, 0, 0, 0); //四种花色、大小王都还没有被抽取
-
- if (res > INF / 2) //因为是浮点数,不能用等号判断是不是相等,简单的办法就是INF/2
- puts("-1.000");
- else
- printf("%.3f\n", res);
- return 0;
-}
-```
-
-### 四、期望值为什么初始化为$1$?
-
-$f[i]$: 从$i$卡牌状态到终点状态所需要的**期望卡牌数**
-
-每次抽一张牌变到下个状态,所以每条路径的权值为$1$
-
-$$\large f[v]=p_1×(f[1]+1)+p_2×(f[2]+1)+p_3×(f[3]+1)+…+p_k×(f[k]+1) = \\
-\sum_{i=1}^{k}p_i+\sum_{i=1}^{k}p_i \times f[i]
-$$
-
- 因为$v$一定能到达下个局面,所以下个状态的概率和为$1$,这里的$\large \displaystyle \sum_{i=1}^{k}p_i=1$ 那么就有:$\displaystyle \large f[v]=1+\sum_{i=1}^{k}p_i \times f[i]$
-综上这里的$f[v]$可以初始化为$1$!
-
\ No newline at end of file
diff --git a/TangDou/AcWing/Math/QiWang/218_dp.cpp b/TangDou/AcWing/Math/QiWang/218_dp.cpp
deleted file mode 100644
index ca614d3..0000000
--- a/TangDou/AcWing/Math/QiWang/218_dp.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-#include
-using namespace std;
-const int INF = 0x3f3f3f3f;
-const int N = 15;
-double f[N][N][N][N][5][5];
-int a, b, c, d;
-int main() {
- memset(f, -1, sizeof f);
- cin >> a >> b >> c >> d;
-
- for (int i = 13; i >= 0; i--)
- for (int j = 13; j >= 0; j--)
- for (int k = 13; k >= 0; k--)
- for (int w = 13; w >= 0; w--)
- for (int x = 4; x >= 0; x--)
- for (int y = 4; y >= 0; y--) {
- double &v = f[i][j][k][w][x][y];
- if (i + (x == 1) + (y == 1) >= a && j + (x == 2) + (y == 2) >= b
- && k + (x == 3) + (y == 3) >= c && w + (x == 4) + (y == 4) >= d) {
- v = 0;
- continue;
- }
-
- v = 1;
- int sum = i + j + k + w + (x != 0) + (y != 0);
- if (i < 13) v += f[i + 1][j][k][w][x][y] * (13 - i) / (54 - sum);
- if (j < 13) v += f[i][j + 1][k][w][x][y] * (13 - j) / (54 - sum);
- if (k < 13) v += f[i][j][k + 1][w][x][y] * (13 - k) / (54 - sum);
- if (w < 13) v += f[i][j][k][w + 1][x][y] * (13 - w) / (54 - sum);
- if (x == 0) {
- double t = INF;
- for (int u = 1; u <= 4; u++) t = min(t, f[i][j][k][w][u][y] / (54 - sum));
- v += t;
- }
- if (y == 0) {
- double t = INF;
- for (int u = 1; u <= 4; u++) t = min(t, f[i][j][k][w][x][u] / (54 - sum));
- v += t;
- }
- }
-
- if (f[0][0][0][0][0][0] > 54)
- printf("-1.000");
- else
- printf("%.3lf", f[0][0][0][0][0][0]);
-
- return 0;
-}
\ No newline at end of file
diff --git a/TangDou/AcWing/Math/QiWang/218_dfs.cpp b/TangDou/AcWing_TiGao/T5/QiWang/218.cpp
similarity index 100%
rename from TangDou/AcWing/Math/QiWang/218_dfs.cpp
rename to TangDou/AcWing_TiGao/T5/QiWang/218.cpp
diff --git a/TangDou/AcWing_TiGao/T5/QiWang/218_dfs.cpp b/TangDou/AcWing_TiGao/T5/QiWang/218_dfs.cpp
deleted file mode 100644
index cb9302e..0000000
--- a/TangDou/AcWing_TiGao/T5/QiWang/218_dfs.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-#include
-using namespace std;
-const int N = 15;
-const int INF = 0x3f3f3f3f;
-double f[N][N][N][N][5][5];
-int st[N][N][N][N][5][5];
-int A, B, C, D;
-
-//如果大小王翻出来放1里,则a++,放2里b++,...
-void add(int &a, int &b, int &c, int &d, int x) {
- if (x == 1) a++;
- if (x == 2) b++;
- if (x == 3) c++;
- if (x == 4) d++;
-}
-
-/*
-功能:计算当前状态f(a,b,c,d,x,y)下的期望值
-*/
-double dfs(int a, int b, int c, int d, int x, int y) {
- //记忆化,同时因为f为double类型,不能使用传统的memset(0x3f)之类
- //进行初始化并判断是否修改过,只能再开一个st数组
- if (st[a][b][c][d][x][y]) return f[a][b][c][d][x][y];
- st[a][b][c][d][x][y] = 1;
-
- //递归出口:当前状态是否到达目标状态,目标状态的期望值是0
- int ta = a, tb = b, tc = c, td = d; //抄出来
- add(ta, tb, tc, td, x), add(ta, tb, tc, td, y); //大王小王会改变四个花色的数量
- if (ta >= A && tb >= B && tc >= C && td >= D) return 0;
-
- //当前状态下的剩余牌数量
- int rst = 54 - ta - tb - tc - td;
- if (rst == 0) return INF; //还没有完成目标,没有剩余的牌了,无解
-
- //当前状态可以向哪些状态转移
- // Q:v为什么要初始化为1?
- // A:看题解内容
- double v = 1;
- if (a < 13) //黑桃有剩余,可能选出的是黑桃
- v += dfs(a + 1, b, c, d, x, y) * (13 - a) / rst;
- if (b < 13) //红桃有剩余,可能选出的是红桃
- v += dfs(a, b + 1, c, d, x, y) * (13 - b) / rst;
- if (c < 13) //梅花有剩余,可能选出的是梅花
- v += dfs(a, b, c + 1, d, x, y) * (13 - c) / rst;
- if (d < 13) //方块有剩余,可能选出的是方块
- v += dfs(a, b, c, d + 1, x, y) * (13 - d) / rst;
-
- //如果小王没有被选出
- if (x == 0)
- v += min(min(dfs(a, b, c, d, 1, y), dfs(a, b, c, d, 2, y)), min(dfs(a, b, c, d, 3, y), dfs(a, b, c, d, 4, y))) / rst;
-
- //如果大王没有被选出
- if (y == 0)
- v += min(min(dfs(a, b, c, d, x, 1), dfs(a, b, c, d, x, 2)), min(dfs(a, b, c, d, x, 3), dfs(a, b, c, d, x, 4))) / rst;
-
- return f[a][b][c][d][x][y] = v;
-}
-
-int main() {
- cin >> A >> B >> C >> D;
- //① 终点状态不唯一,起点是唯的的,所以以起点为终点,以终点为起点,反着推
- //② AcWing 217. 绿豆蛙的归宿 需要建图,本题不用建图
- double res = dfs(0, 0, 0, 0, 0, 0); //四种花色、大小王都还没有被抽取
-
- if (res > INF / 2) //因为是浮点数,不能用等号判断是不是相等,简单的办法就是INF/2
- puts("-1.000");
- else
- printf("%.3f\n", res);
- return 0;
-}
\ No newline at end of file
diff --git a/TangDou/AcWing_TiGao/T5/QiWang/218_dp.cpp b/TangDou/AcWing_TiGao/T5/QiWang/218_dp.cpp
deleted file mode 100644
index ca614d3..0000000
--- a/TangDou/AcWing_TiGao/T5/QiWang/218_dp.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-#include
-using namespace std;
-const int INF = 0x3f3f3f3f;
-const int N = 15;
-double f[N][N][N][N][5][5];
-int a, b, c, d;
-int main() {
- memset(f, -1, sizeof f);
- cin >> a >> b >> c >> d;
-
- for (int i = 13; i >= 0; i--)
- for (int j = 13; j >= 0; j--)
- for (int k = 13; k >= 0; k--)
- for (int w = 13; w >= 0; w--)
- for (int x = 4; x >= 0; x--)
- for (int y = 4; y >= 0; y--) {
- double &v = f[i][j][k][w][x][y];
- if (i + (x == 1) + (y == 1) >= a && j + (x == 2) + (y == 2) >= b
- && k + (x == 3) + (y == 3) >= c && w + (x == 4) + (y == 4) >= d) {
- v = 0;
- continue;
- }
-
- v = 1;
- int sum = i + j + k + w + (x != 0) + (y != 0);
- if (i < 13) v += f[i + 1][j][k][w][x][y] * (13 - i) / (54 - sum);
- if (j < 13) v += f[i][j + 1][k][w][x][y] * (13 - j) / (54 - sum);
- if (k < 13) v += f[i][j][k + 1][w][x][y] * (13 - k) / (54 - sum);
- if (w < 13) v += f[i][j][k][w + 1][x][y] * (13 - w) / (54 - sum);
- if (x == 0) {
- double t = INF;
- for (int u = 1; u <= 4; u++) t = min(t, f[i][j][k][w][u][y] / (54 - sum));
- v += t;
- }
- if (y == 0) {
- double t = INF;
- for (int u = 1; u <= 4; u++) t = min(t, f[i][j][k][w][x][u] / (54 - sum));
- v += t;
- }
- }
-
- if (f[0][0][0][0][0][0] > 54)
- printf("-1.000");
- else
- printf("%.3lf", f[0][0][0][0][0][0]);
-
- return 0;
-}
\ No newline at end of file
From ec00ad86512665560b0578a4bb38b7dd1502496b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=84=E6=B5=B7?= <10402852@qq.com>
Date: Mon, 25 Dec 2023 07:59:17 +0800
Subject: [PATCH 02/87] 'commit'
---
TangDou/AcWing_TiGao/T5/QiWang/218.cpp | 42 +++++++++++++-------------
TangDou/AcWing_TiGao/T5/QiWang/218.md | 4 ---
2 files changed, 21 insertions(+), 25 deletions(-)
diff --git a/TangDou/AcWing_TiGao/T5/QiWang/218.cpp b/TangDou/AcWing_TiGao/T5/QiWang/218.cpp
index cb9302e..6c93b5a 100644
--- a/TangDou/AcWing_TiGao/T5/QiWang/218.cpp
+++ b/TangDou/AcWing_TiGao/T5/QiWang/218.cpp
@@ -6,7 +6,7 @@ double f[N][N][N][N][5][5];
int st[N][N][N][N][5][5];
int A, B, C, D;
-//如果大小王翻出来放1里,则a++,放2里b++,...
+// 如果大小王翻出来放1里,则a++,放2里b++,...
void add(int &a, int &b, int &c, int &d, int x) {
if (x == 1) a++;
if (x == 2) b++;
@@ -18,38 +18,38 @@ void add(int &a, int &b, int &c, int &d, int x) {
功能:计算当前状态f(a,b,c,d,x,y)下的期望值
*/
double dfs(int a, int b, int c, int d, int x, int y) {
- //记忆化,同时因为f为double类型,不能使用传统的memset(0x3f)之类
- //进行初始化并判断是否修改过,只能再开一个st数组
+ // 记忆化,同时因为f为double类型,不能使用传统的memset(0x3f)之类
+ // 进行初始化并判断是否修改过,只能再开一个st数组
if (st[a][b][c][d][x][y]) return f[a][b][c][d][x][y];
st[a][b][c][d][x][y] = 1;
- //递归出口:当前状态是否到达目标状态,目标状态的期望值是0
- int ta = a, tb = b, tc = c, td = d; //抄出来
- add(ta, tb, tc, td, x), add(ta, tb, tc, td, y); //大王小王会改变四个花色的数量
+ // 递归出口:当前状态是否到达目标状态,目标状态的期望值是0
+ int ta = a, tb = b, tc = c, td = d; // 抄出来
+ add(ta, tb, tc, td, x), add(ta, tb, tc, td, y); // 大王小王会改变四个花色的数量
if (ta >= A && tb >= B && tc >= C && td >= D) return 0;
- //当前状态下的剩余牌数量
+ // 当前状态下的剩余牌数量
int rst = 54 - ta - tb - tc - td;
- if (rst == 0) return INF; //还没有完成目标,没有剩余的牌了,无解
+ if (rst == 0) return INF; // 还没有完成目标,没有剩余的牌了,无解
- //当前状态可以向哪些状态转移
- // Q:v为什么要初始化为1?
- // A:看题解内容
+ // 当前状态可以向哪些状态转移
+ // Q:v为什么要初始化为1?
+ // A:看题解内容
double v = 1;
- if (a < 13) //黑桃有剩余,可能选出的是黑桃
+ if (a < 13) // 黑桃有剩余,可能选出的是黑桃
v += dfs(a + 1, b, c, d, x, y) * (13 - a) / rst;
- if (b < 13) //红桃有剩余,可能选出的是红桃
+ if (b < 13) // 红桃有剩余,可能选出的是红桃
v += dfs(a, b + 1, c, d, x, y) * (13 - b) / rst;
- if (c < 13) //梅花有剩余,可能选出的是梅花
+ if (c < 13) // 梅花有剩余,可能选出的是梅花
v += dfs(a, b, c + 1, d, x, y) * (13 - c) / rst;
- if (d < 13) //方块有剩余,可能选出的是方块
+ if (d < 13) // 方块有剩余,可能选出的是方块
v += dfs(a, b, c, d + 1, x, y) * (13 - d) / rst;
- //如果小王没有被选出
+ // 如果小王没有被选出
if (x == 0)
v += min(min(dfs(a, b, c, d, 1, y), dfs(a, b, c, d, 2, y)), min(dfs(a, b, c, d, 3, y), dfs(a, b, c, d, 4, y))) / rst;
- //如果大王没有被选出
+ // 如果大王没有被选出
if (y == 0)
v += min(min(dfs(a, b, c, d, x, 1), dfs(a, b, c, d, x, 2)), min(dfs(a, b, c, d, x, 3), dfs(a, b, c, d, x, 4))) / rst;
@@ -58,11 +58,11 @@ double dfs(int a, int b, int c, int d, int x, int y) {
int main() {
cin >> A >> B >> C >> D;
- //① 终点状态不唯一,起点是唯的的,所以以起点为终点,以终点为起点,反着推
- //② AcWing 217. 绿豆蛙的归宿 需要建图,本题不用建图
- double res = dfs(0, 0, 0, 0, 0, 0); //四种花色、大小王都还没有被抽取
+ // ① 起点状态不唯一,终点是唯一的,所以以起点为终点,以终点为起点,反着推
+ // ② AcWing 217. 绿豆蛙的归宿 需要建图,本题转移关系清晰,不用建图
+ double res = dfs(0, 0, 0, 0, 0, 0); // 四种花色、大小王都还没有被抽取
- if (res > INF / 2) //因为是浮点数,不能用等号判断是不是相等,简单的办法就是INF/2
+ if (res > INF / 2) // 因为是浮点数,不能用等号判断是不是相等,简单的办法就是INF/2
puts("-1.000");
else
printf("%.3f\n", res);
diff --git a/TangDou/AcWing_TiGao/T5/QiWang/218.md b/TangDou/AcWing_TiGao/T5/QiWang/218.md
index a4c716a..f230d1b 100644
--- a/TangDou/AcWing_TiGao/T5/QiWang/218.md
+++ b/TangDou/AcWing_TiGao/T5/QiWang/218.md
@@ -38,10 +38,6 @@ $0≤A,B,C,D≤15$
### 二、题意分析
-$Q$:为什么从终止状态向起始状态递推?
-
-**答**:满足条件的终止状态较多,而起始状态唯一。考虑以终止状态为初值,起始状态为目标,进行动态规划。
-
#### 状态表示
$f[a][b][c][d][x][y]$ : 当前已翻开状态下,还需翻开牌的数量 **期望数**。
From e6fa8bbec06621974b1942978a0eb197f4f76a56 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=84=E6=B5=B7?= <10402852@qq.com>
Date: Mon, 25 Dec 2023 11:22:25 +0800
Subject: [PATCH 03/87] 'commit'
---
TangDou/AcWing_TiGao/T5/QiWang/218.cpp | 20 +++----
TangDou/AcWing_TiGao/T5/QiWang/218.md | 72 ++++++++++++++------------
2 files changed, 47 insertions(+), 45 deletions(-)
diff --git a/TangDou/AcWing_TiGao/T5/QiWang/218.cpp b/TangDou/AcWing_TiGao/T5/QiWang/218.cpp
index 6c93b5a..65bca6b 100644
--- a/TangDou/AcWing_TiGao/T5/QiWang/218.cpp
+++ b/TangDou/AcWing_TiGao/T5/QiWang/218.cpp
@@ -3,7 +3,6 @@ using namespace std;
const int N = 15;
const int INF = 0x3f3f3f3f;
double f[N][N][N][N][5][5];
-int st[N][N][N][N][5][5];
int A, B, C, D;
// 如果大小王翻出来放1里,则a++,放2里b++,...
@@ -18,23 +17,19 @@ void add(int &a, int &b, int &c, int &d, int x) {
功能:计算当前状态f(a,b,c,d,x,y)下的期望值
*/
double dfs(int a, int b, int c, int d, int x, int y) {
- // 记忆化,同时因为f为double类型,不能使用传统的memset(0x3f)之类
- // 进行初始化并判断是否修改过,只能再开一个st数组
- if (st[a][b][c][d][x][y]) return f[a][b][c][d][x][y];
- st[a][b][c][d][x][y] = 1;
+ // 记忆化搜索
+ if (f[a][b][c][d][x][y] > 0) return f[a][b][c][d][x][y];
// 递归出口:当前状态是否到达目标状态,目标状态的期望值是0
- int ta = a, tb = b, tc = c, td = d; // 抄出来
- add(ta, tb, tc, td, x), add(ta, tb, tc, td, y); // 大王小王会改变四个花色的数量
- if (ta >= A && tb >= B && tc >= C && td >= D) return 0;
+ int ta = a, tb = b, tc = c, td = d; // 抄出来
+ add(ta, tb, tc, td, x), add(ta, tb, tc, td, y); // 大王小王会改变四个花色的数量
+ if (ta >= A && tb >= B && tc >= C && td >= D) return 0; // 如果条件全满足就是终止状态
// 当前状态下的剩余牌数量
int rst = 54 - ta - tb - tc - td;
- if (rst == 0) return INF; // 还没有完成目标,没有剩余的牌了,无解
+ if (rst <= 0) return INF; // 还没有完成目标,没有剩余的牌了,无解
// 当前状态可以向哪些状态转移
- // Q:v为什么要初始化为1?
- // A:看题解内容
double v = 1;
if (a < 13) // 黑桃有剩余,可能选出的是黑桃
v += dfs(a + 1, b, c, d, x, y) * (13 - a) / rst;
@@ -58,8 +53,7 @@ double dfs(int a, int b, int c, int d, int x, int y) {
int main() {
cin >> A >> B >> C >> D;
- // ① 起点状态不唯一,终点是唯一的,所以以起点为终点,以终点为起点,反着推
- // ② AcWing 217. 绿豆蛙的归宿 需要建图,本题转移关系清晰,不用建图
+
double res = dfs(0, 0, 0, 0, 0, 0); // 四种花色、大小王都还没有被抽取
if (res > INF / 2) // 因为是浮点数,不能用等号判断是不是相等,简单的办法就是INF/2
diff --git a/TangDou/AcWing_TiGao/T5/QiWang/218.md b/TangDou/AcWing_TiGao/T5/QiWang/218.md
index f230d1b..22c5065 100644
--- a/TangDou/AcWing_TiGao/T5/QiWang/218.md
+++ b/TangDou/AcWing_TiGao/T5/QiWang/218.md
@@ -13,6 +13,18 @@ $Rainbow$ 想问问 $Admin$,得到 $A$ 张黑桃、$B$ 张红桃、$C$ 张梅
特殊地,如果翻开的牌是大王或者小王,$Admin$ 将会把它作为某种花色的牌放入对应堆中,使得放入之后 $E$的值尽可能小。
+> 注:从牌堆里面翻出来的牌的期望张数最少是多少?
+> **期望**:用初等数学的语言去描述,就是平均值是多少。
+> $Q:$为什么会有最少的概念出现的呢?这个数量不是固定的吗?
+> 答:这是因为大王和小王可以被认为是其中四个花色中的某一种花色,这就导致产生了不同的事件。
+> 放到红桃里是一种事件,放到黑桃里是一种事件,...,这四个事件的期望不一定相同!
+> 选择就在大小王上,我们要选择一个期望张数最少的放法,问我们这个期望张数最小是多少。
+
+###$yxc$经典语录
+> **图中,点是状态表示,边是状态转移**。
+> **理解**:前一个题中,需要建图,建图完成后才能用图进行状态表示和状态转移,本题,状态表示和状态转移都是很明确的,不需要建图。
+> **总结** :动态规划是精髓,建图与否是表象。
+
由于 $Admin$ 和 $Rainbow$ 还在玩扑克,所以这个程序就交给你来写了。
**输入格式**
@@ -66,10 +78,9 @@ using namespace std;
const int N = 15;
const int INF = 0x3f3f3f3f;
double f[N][N][N][N][5][5];
-int st[N][N][N][N][5][5];
int A, B, C, D;
-//如果大小王翻出来放1里,则a++,放2里b++,...
+// 如果大小王翻出来放1里,则a++,放2里b++,...
void add(int &a, int &b, int &c, int &d, int x) {
if (x == 1) a++;
if (x == 2) b++;
@@ -81,38 +92,34 @@ void add(int &a, int &b, int &c, int &d, int x) {
功能:计算当前状态f(a,b,c,d,x,y)下的期望值
*/
double dfs(int a, int b, int c, int d, int x, int y) {
- //记忆化,同时因为f为double类型,不能使用传统的memset(0x3f)之类
- //进行初始化并判断是否修改过,只能再开一个st数组
- if (st[a][b][c][d][x][y]) return f[a][b][c][d][x][y];
- st[a][b][c][d][x][y] = 1;
+ // 记忆化搜索
+ if (f[a][b][c][d][x][y] > 0) return f[a][b][c][d][x][y];
- //递归出口:当前状态是否到达目标状态,目标状态的期望值是0
- int ta = a, tb = b, tc = c, td = d; //抄出来
- add(ta, tb, tc, td, x), add(ta, tb, tc, td, y); //大王小王会改变四个花色的数量
- if (ta >= A && tb >= B && tc >= C && td >= D) return 0;
+ // 递归出口:当前状态是否到达目标状态,目标状态的期望值是0
+ int ta = a, tb = b, tc = c, td = d; // 抄出来
+ add(ta, tb, tc, td, x), add(ta, tb, tc, td, y); // 大王小王会改变四个花色的数量
+ if (ta >= A && tb >= B && tc >= C && td >= D) return 0; // 如果条件全满足就是终止状态
- //当前状态下的剩余牌数量
+ // 当前状态下的剩余牌数量
int rst = 54 - ta - tb - tc - td;
- if (rst == 0) return INF; //还没有完成目标,没有剩余的牌了,无解
+ if (rst <= 0) return INF; // 还没有完成目标,没有剩余的牌了,无解
- //当前状态可以向哪些状态转移
- // Q:v为什么要初始化为1?
- // A:看题解内容
+ // 当前状态可以向哪些状态转移
double v = 1;
- if (a < 13) //黑桃有剩余,可能选出的是黑桃
+ if (a < 13) // 黑桃有剩余,可能选出的是黑桃
v += dfs(a + 1, b, c, d, x, y) * (13 - a) / rst;
- if (b < 13) //红桃有剩余,可能选出的是红桃
+ if (b < 13) // 红桃有剩余,可能选出的是红桃
v += dfs(a, b + 1, c, d, x, y) * (13 - b) / rst;
- if (c < 13) //梅花有剩余,可能选出的是梅花
+ if (c < 13) // 梅花有剩余,可能选出的是梅花
v += dfs(a, b, c + 1, d, x, y) * (13 - c) / rst;
- if (d < 13) //方块有剩余,可能选出的是方块
+ if (d < 13) // 方块有剩余,可能选出的是方块
v += dfs(a, b, c, d + 1, x, y) * (13 - d) / rst;
- //如果小王没有被选出
+ // 如果小王没有被选出
if (x == 0)
v += min(min(dfs(a, b, c, d, 1, y), dfs(a, b, c, d, 2, y)), min(dfs(a, b, c, d, 3, y), dfs(a, b, c, d, 4, y))) / rst;
- //如果大王没有被选出
+ // 如果大王没有被选出
if (y == 0)
v += min(min(dfs(a, b, c, d, x, 1), dfs(a, b, c, d, x, 2)), min(dfs(a, b, c, d, x, 3), dfs(a, b, c, d, x, 4))) / rst;
@@ -121,11 +128,10 @@ double dfs(int a, int b, int c, int d, int x, int y) {
int main() {
cin >> A >> B >> C >> D;
- //① 终点状态不唯一,起点是唯的的,所以以起点为终点,以终点为起点,反着推
- //② AcWing 217. 绿豆蛙的归宿 需要建图,本题不用建图
- double res = dfs(0, 0, 0, 0, 0, 0); //四种花色、大小王都还没有被抽取
- if (res > INF / 2) //因为是浮点数,不能用等号判断是不是相等,简单的办法就是INF/2
+ double res = dfs(0, 0, 0, 0, 0, 0); // 四种花色、大小王都还没有被抽取
+
+ if (res > INF / 2) // 因为是浮点数,不能用等号判断是不是相等,简单的办法就是INF/2
puts("-1.000");
else
printf("%.3f\n", res);
@@ -133,16 +139,18 @@ int main() {
}
```
-### 四、期望值为什么初始化为$1$?
+#### $Q$:期望值为什么初始化为$1$?
-$f[i]$: 从$i$卡牌状态到终点状态所需要的**期望卡牌数**
+
+
+$f[v_i]$: 从$i$卡牌状态到终点状态所需要的**期望卡牌数**
每次抽一张牌变到下个状态,所以每条路径的权值为$1$
-$$\large f[v]=p_1×(f[1]+1)+p_2×(f[2]+1)+p_3×(f[3]+1)+…+p_k×(f[k]+1) = \\
-\sum_{i=1}^{k}p_i+\sum_{i=1}^{k}p_i \times f[i]
+$$\large f[v]=p_1×(f[v_1]+1)+p_2×(f[v_2]+1)+p_3×(f[v_3]+1)+…+p_k×(f[v_k]+1) = \\
+\sum_{i=1}^{k}p_i+\sum_{i=1}^{k}p_i \times f[v_i]
$$
- 因为$v$一定能到达下个局面,所以下个状态的概率和为$1$,这里的$\large \displaystyle \sum_{i=1}^{k}p_i=1$ 那么就有:$\displaystyle \large f[v]=1+\sum_{i=1}^{k}p_i \times f[i]$
-综上这里的$f[v]$可以初始化为$1$!
-
\ No newline at end of file
+ 因为$v$一定能到达下个局面,所以下个状态的概率和为$1$,这里的$\large \displaystyle \sum_{i=1}^{k}p_i=1$ 那么就有:$\displaystyle \large f[v]=1+\sum_{i=1}^{k}p_i \times f[v_i]$
+综上这里的$f[v]$可以初始化为$1$。
+
From 699ad726e3c095f0cd96e12d792cb45aaa73def9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=84=E6=B5=B7?= <10402852@qq.com>
Date: Mon, 25 Dec 2023 13:07:45 +0800
Subject: [PATCH 04/87] 'commit'
---
.../Math => AcWing_TiGao/T5}/GameTheory/1319.cpp | 0
.../Math => AcWing_TiGao/T5}/GameTheory/1319.md | 7 ++++---
.../Math => AcWing_TiGao/T5}/GameTheory/1321.md | 0
.../Math => AcWing_TiGao/T5}/GameTheory/1321_1.cpp | 0
.../Math => AcWing_TiGao/T5}/GameTheory/1321_2.cpp | 0
.../Math => AcWing_TiGao/T5}/GameTheory/1322.cpp | 0
.../Math => AcWing_TiGao/T5}/GameTheory/1322.md | 0
.../Math => AcWing_TiGao/T5}/GameTheory/1322.vsdx | Bin
.../Math => AcWing_TiGao/T5}/GameTheory/HDU1730.cpp | 0
.../Math => AcWing_TiGao/T5}/GameTheory/HDU1730.md | 0
.../Math => AcWing_TiGao/T5}/GameTheory/HDU1846.cpp | 0
.../Math => AcWing_TiGao/T5}/GameTheory/HDU1847.cpp | 0
.../Math => AcWing_TiGao/T5}/GameTheory/HDU1850.cpp | 0
.../Math => AcWing_TiGao/T5}/GameTheory/HDU2176.cpp | 0
.../Math => AcWing_TiGao/T5}/GameTheory/HDU2188.cpp | 0
.../Math => AcWing_TiGao/T5}/GameTheory/HDU4315.cpp | 0
.../Math => AcWing_TiGao/T5}/GameTheory/HDU4315.md | 0
.../T5}/GameTheory/POJ1704.drawio | 0
.../Math => AcWing_TiGao/T5}/GameTheory/POJ1704.md | 0
.../T5}/GameTheory/POJ1704_Nim.cpp | 0
.../T5}/GameTheory/POJ1704_StaircaseNim_7.cpp | 0
.../T5}/GameTheory/POJ1704_StaircaseNim_8.cpp | 0
.../Math => AcWing_TiGao/T5}/GameTheory/test.cpp | 0
.../T5}/GameTheory/不一样的博弈论笔记.md | 0
.../T5}/GameTheory/博弈论.md | 0
25 files changed, 4 insertions(+), 3 deletions(-)
rename TangDou/{AcWing/Math => AcWing_TiGao/T5}/GameTheory/1319.cpp (100%)
rename TangDou/{AcWing/Math => AcWing_TiGao/T5}/GameTheory/1319.md (89%)
rename TangDou/{AcWing/Math => AcWing_TiGao/T5}/GameTheory/1321.md (100%)
rename TangDou/{AcWing/Math => AcWing_TiGao/T5}/GameTheory/1321_1.cpp (100%)
rename TangDou/{AcWing/Math => AcWing_TiGao/T5}/GameTheory/1321_2.cpp (100%)
rename TangDou/{AcWing/Math => AcWing_TiGao/T5}/GameTheory/1322.cpp (100%)
rename TangDou/{AcWing/Math => AcWing_TiGao/T5}/GameTheory/1322.md (100%)
rename TangDou/{AcWing/Math => AcWing_TiGao/T5}/GameTheory/1322.vsdx (100%)
rename TangDou/{AcWing/Math => AcWing_TiGao/T5}/GameTheory/HDU1730.cpp (100%)
rename TangDou/{AcWing/Math => AcWing_TiGao/T5}/GameTheory/HDU1730.md (100%)
rename TangDou/{AcWing/Math => AcWing_TiGao/T5}/GameTheory/HDU1846.cpp (100%)
rename TangDou/{AcWing/Math => AcWing_TiGao/T5}/GameTheory/HDU1847.cpp (100%)
rename TangDou/{AcWing/Math => AcWing_TiGao/T5}/GameTheory/HDU1850.cpp (100%)
rename TangDou/{AcWing/Math => AcWing_TiGao/T5}/GameTheory/HDU2176.cpp (100%)
rename TangDou/{AcWing/Math => AcWing_TiGao/T5}/GameTheory/HDU2188.cpp (100%)
rename TangDou/{AcWing/Math => AcWing_TiGao/T5}/GameTheory/HDU4315.cpp (100%)
rename TangDou/{AcWing/Math => AcWing_TiGao/T5}/GameTheory/HDU4315.md (100%)
rename TangDou/{AcWing/Math => AcWing_TiGao/T5}/GameTheory/POJ1704.drawio (100%)
rename TangDou/{AcWing/Math => AcWing_TiGao/T5}/GameTheory/POJ1704.md (100%)
rename TangDou/{AcWing/Math => AcWing_TiGao/T5}/GameTheory/POJ1704_Nim.cpp (100%)
rename TangDou/{AcWing/Math => AcWing_TiGao/T5}/GameTheory/POJ1704_StaircaseNim_7.cpp (100%)
rename TangDou/{AcWing/Math => AcWing_TiGao/T5}/GameTheory/POJ1704_StaircaseNim_8.cpp (100%)
rename TangDou/{AcWing/Math => AcWing_TiGao/T5}/GameTheory/test.cpp (100%)
rename TangDou/{AcWing/Math => AcWing_TiGao/T5}/GameTheory/不一样的博弈论笔记.md (100%)
rename TangDou/{AcWing/Math => AcWing_TiGao/T5}/GameTheory/博弈论.md (100%)
diff --git a/TangDou/AcWing/Math/GameTheory/1319.cpp b/TangDou/AcWing_TiGao/T5/GameTheory/1319.cpp
similarity index 100%
rename from TangDou/AcWing/Math/GameTheory/1319.cpp
rename to TangDou/AcWing_TiGao/T5/GameTheory/1319.cpp
diff --git a/TangDou/AcWing/Math/GameTheory/1319.md b/TangDou/AcWing_TiGao/T5/GameTheory/1319.md
similarity index 89%
rename from TangDou/AcWing/Math/GameTheory/1319.md
rename to TangDou/AcWing_TiGao/T5/GameTheory/1319.md
index 0e8c8c4..17ae03b 100644
--- a/TangDou/AcWing/Math/GameTheory/1319.md
+++ b/TangDou/AcWing_TiGao/T5/GameTheory/1319.md
@@ -47,15 +47,16 @@ win
例:$mex({1,2})=0,mex({0,1})=2,mex({0,1,2,4})=3$
-在一张有向无环图中,对于每个点 $u$,设其**所有能到的点**的 $SG$ 函数值集合为集合 $A$,那么 $u$ 的 $SG$ 函数值为 $mex(A)$,记做 $SG(u)=mex(A)$
-例图:
+在一张有向无环图中,对于每个点 $u$,设其 **所有能到的点** 的 $SG$ 函数值集合为集合 $A$,那么 $u$ 的 $SG$ 函数值为 $mex(A)$,记做 $SG(u)=mex(A)$
+
+如图:
例图解释:
$SG(5)=mex({\phi})=0$
$SG(3)=mex({SG(5)})=mex({0})=1$
$SG(4)=mex({SG(5),SG(3)})=mex({0,1})=2$
-$SG(2)=mex({SG(3)}=mex({1})=0$
+$SG(2)=mex({SG(3)})=mex({1})=0$
$SG(1)=mex({SG(2),SG(4)})=mex({0,2})=1$
#### 本题思路
diff --git a/TangDou/AcWing/Math/GameTheory/1321.md b/TangDou/AcWing_TiGao/T5/GameTheory/1321.md
similarity index 100%
rename from TangDou/AcWing/Math/GameTheory/1321.md
rename to TangDou/AcWing_TiGao/T5/GameTheory/1321.md
diff --git a/TangDou/AcWing/Math/GameTheory/1321_1.cpp b/TangDou/AcWing_TiGao/T5/GameTheory/1321_1.cpp
similarity index 100%
rename from TangDou/AcWing/Math/GameTheory/1321_1.cpp
rename to TangDou/AcWing_TiGao/T5/GameTheory/1321_1.cpp
diff --git a/TangDou/AcWing/Math/GameTheory/1321_2.cpp b/TangDou/AcWing_TiGao/T5/GameTheory/1321_2.cpp
similarity index 100%
rename from TangDou/AcWing/Math/GameTheory/1321_2.cpp
rename to TangDou/AcWing_TiGao/T5/GameTheory/1321_2.cpp
diff --git a/TangDou/AcWing/Math/GameTheory/1322.cpp b/TangDou/AcWing_TiGao/T5/GameTheory/1322.cpp
similarity index 100%
rename from TangDou/AcWing/Math/GameTheory/1322.cpp
rename to TangDou/AcWing_TiGao/T5/GameTheory/1322.cpp
diff --git a/TangDou/AcWing/Math/GameTheory/1322.md b/TangDou/AcWing_TiGao/T5/GameTheory/1322.md
similarity index 100%
rename from TangDou/AcWing/Math/GameTheory/1322.md
rename to TangDou/AcWing_TiGao/T5/GameTheory/1322.md
diff --git a/TangDou/AcWing/Math/GameTheory/1322.vsdx b/TangDou/AcWing_TiGao/T5/GameTheory/1322.vsdx
similarity index 100%
rename from TangDou/AcWing/Math/GameTheory/1322.vsdx
rename to TangDou/AcWing_TiGao/T5/GameTheory/1322.vsdx
diff --git a/TangDou/AcWing/Math/GameTheory/HDU1730.cpp b/TangDou/AcWing_TiGao/T5/GameTheory/HDU1730.cpp
similarity index 100%
rename from TangDou/AcWing/Math/GameTheory/HDU1730.cpp
rename to TangDou/AcWing_TiGao/T5/GameTheory/HDU1730.cpp
diff --git a/TangDou/AcWing/Math/GameTheory/HDU1730.md b/TangDou/AcWing_TiGao/T5/GameTheory/HDU1730.md
similarity index 100%
rename from TangDou/AcWing/Math/GameTheory/HDU1730.md
rename to TangDou/AcWing_TiGao/T5/GameTheory/HDU1730.md
diff --git a/TangDou/AcWing/Math/GameTheory/HDU1846.cpp b/TangDou/AcWing_TiGao/T5/GameTheory/HDU1846.cpp
similarity index 100%
rename from TangDou/AcWing/Math/GameTheory/HDU1846.cpp
rename to TangDou/AcWing_TiGao/T5/GameTheory/HDU1846.cpp
diff --git a/TangDou/AcWing/Math/GameTheory/HDU1847.cpp b/TangDou/AcWing_TiGao/T5/GameTheory/HDU1847.cpp
similarity index 100%
rename from TangDou/AcWing/Math/GameTheory/HDU1847.cpp
rename to TangDou/AcWing_TiGao/T5/GameTheory/HDU1847.cpp
diff --git a/TangDou/AcWing/Math/GameTheory/HDU1850.cpp b/TangDou/AcWing_TiGao/T5/GameTheory/HDU1850.cpp
similarity index 100%
rename from TangDou/AcWing/Math/GameTheory/HDU1850.cpp
rename to TangDou/AcWing_TiGao/T5/GameTheory/HDU1850.cpp
diff --git a/TangDou/AcWing/Math/GameTheory/HDU2176.cpp b/TangDou/AcWing_TiGao/T5/GameTheory/HDU2176.cpp
similarity index 100%
rename from TangDou/AcWing/Math/GameTheory/HDU2176.cpp
rename to TangDou/AcWing_TiGao/T5/GameTheory/HDU2176.cpp
diff --git a/TangDou/AcWing/Math/GameTheory/HDU2188.cpp b/TangDou/AcWing_TiGao/T5/GameTheory/HDU2188.cpp
similarity index 100%
rename from TangDou/AcWing/Math/GameTheory/HDU2188.cpp
rename to TangDou/AcWing_TiGao/T5/GameTheory/HDU2188.cpp
diff --git a/TangDou/AcWing/Math/GameTheory/HDU4315.cpp b/TangDou/AcWing_TiGao/T5/GameTheory/HDU4315.cpp
similarity index 100%
rename from TangDou/AcWing/Math/GameTheory/HDU4315.cpp
rename to TangDou/AcWing_TiGao/T5/GameTheory/HDU4315.cpp
diff --git a/TangDou/AcWing/Math/GameTheory/HDU4315.md b/TangDou/AcWing_TiGao/T5/GameTheory/HDU4315.md
similarity index 100%
rename from TangDou/AcWing/Math/GameTheory/HDU4315.md
rename to TangDou/AcWing_TiGao/T5/GameTheory/HDU4315.md
diff --git a/TangDou/AcWing/Math/GameTheory/POJ1704.drawio b/TangDou/AcWing_TiGao/T5/GameTheory/POJ1704.drawio
similarity index 100%
rename from TangDou/AcWing/Math/GameTheory/POJ1704.drawio
rename to TangDou/AcWing_TiGao/T5/GameTheory/POJ1704.drawio
diff --git a/TangDou/AcWing/Math/GameTheory/POJ1704.md b/TangDou/AcWing_TiGao/T5/GameTheory/POJ1704.md
similarity index 100%
rename from TangDou/AcWing/Math/GameTheory/POJ1704.md
rename to TangDou/AcWing_TiGao/T5/GameTheory/POJ1704.md
diff --git a/TangDou/AcWing/Math/GameTheory/POJ1704_Nim.cpp b/TangDou/AcWing_TiGao/T5/GameTheory/POJ1704_Nim.cpp
similarity index 100%
rename from TangDou/AcWing/Math/GameTheory/POJ1704_Nim.cpp
rename to TangDou/AcWing_TiGao/T5/GameTheory/POJ1704_Nim.cpp
diff --git a/TangDou/AcWing/Math/GameTheory/POJ1704_StaircaseNim_7.cpp b/TangDou/AcWing_TiGao/T5/GameTheory/POJ1704_StaircaseNim_7.cpp
similarity index 100%
rename from TangDou/AcWing/Math/GameTheory/POJ1704_StaircaseNim_7.cpp
rename to TangDou/AcWing_TiGao/T5/GameTheory/POJ1704_StaircaseNim_7.cpp
diff --git a/TangDou/AcWing/Math/GameTheory/POJ1704_StaircaseNim_8.cpp b/TangDou/AcWing_TiGao/T5/GameTheory/POJ1704_StaircaseNim_8.cpp
similarity index 100%
rename from TangDou/AcWing/Math/GameTheory/POJ1704_StaircaseNim_8.cpp
rename to TangDou/AcWing_TiGao/T5/GameTheory/POJ1704_StaircaseNim_8.cpp
diff --git a/TangDou/AcWing/Math/GameTheory/test.cpp b/TangDou/AcWing_TiGao/T5/GameTheory/test.cpp
similarity index 100%
rename from TangDou/AcWing/Math/GameTheory/test.cpp
rename to TangDou/AcWing_TiGao/T5/GameTheory/test.cpp
diff --git a/TangDou/AcWing/Math/GameTheory/不一样的博弈论笔记.md b/TangDou/AcWing_TiGao/T5/GameTheory/不一样的博弈论笔记.md
similarity index 100%
rename from TangDou/AcWing/Math/GameTheory/不一样的博弈论笔记.md
rename to TangDou/AcWing_TiGao/T5/GameTheory/不一样的博弈论笔记.md
diff --git a/TangDou/AcWing/Math/GameTheory/博弈论.md b/TangDou/AcWing_TiGao/T5/GameTheory/博弈论.md
similarity index 100%
rename from TangDou/AcWing/Math/GameTheory/博弈论.md
rename to TangDou/AcWing_TiGao/T5/GameTheory/博弈论.md
From 234b2167c17a4a66cdf69c33e10315073e5f0b79 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=84=E6=B5=B7?= <10402852@qq.com>
Date: Mon, 25 Dec 2023 14:12:53 +0800
Subject: [PATCH 05/87] 'commit'
---
TangDou/AcWing_TiGao/T5/GameTheory/1319.md | 49 +++++++++++++++++++++-
1 file changed, 48 insertions(+), 1 deletion(-)
diff --git a/TangDou/AcWing_TiGao/T5/GameTheory/1319.md b/TangDou/AcWing_TiGao/T5/GameTheory/1319.md
index 17ae03b..a2adede 100644
--- a/TangDou/AcWing_TiGao/T5/GameTheory/1319.md
+++ b/TangDou/AcWing_TiGao/T5/GameTheory/1319.md
@@ -43,6 +43,7 @@ win
### 二、解题思路
+#### 1、$SG$函数
首先定义 $mex$ 函数,这是施加于一个集合的函数,返回 **最小的不属于这个集合的非负整数**
例:$mex({1,2})=0,mex({0,1})=2,mex({0,1,2,4})=3$
@@ -59,7 +60,53 @@ $SG(4)=mex({SG(5),SG(3)})=mex({0,1})=2$
$SG(2)=mex({SG(3)})=mex({1})=0$
$SG(1)=mex({SG(2),SG(4)})=mex({0,2})=1$
-#### 本题思路
+#### 2、本题和 $SG$ 函数有什么关系?
+下面先说本题做法,再证明该方法正确性。
+
+**做法**:求出每个棋子所在的点的 $SG$ 函数值,将所有值异或起来。若异或值不为 $0$,则输出$win$,否则输出$lose$
+
+**证明**:
+首先,由于这是一张有向无环图,所以游戏最后一定会结束,也就是说每个棋子最后都会移动到一个点上,且该点没有任何能到达的点。
+那么根据定义,结束状态的所有点的 $SG$ 函数值异或起来为 $0$,做法对于结束状态可行。
+所以接下来,只要证明出
+
+- ① 任何一种每个棋子所在点的 $SG$ 函数值异或起来非 $0$ 的情况,一定能通过一次移动棋子,到达一个 每个棋子所在点的 $SG$ 函数值异或起来为 $0$ 的情况
+
+- ② 任何一种每个棋子所在点的 $SG$ 函数值异或起来为 $0$ 的情况,一定不能通过一次移动棋子,到达一个每个棋子所在点的 $SG$ 函数值异或起来为 $0$ 的情况
+
+那么做法就是对的
+
+
+**证明** $1$:
+设每个棋子所在点的 $SG$ 函数值分别为 $a_1,a_2,⋯,a_n$
+设 $x=a_1 XOR a_2 XOR ⋯ XOR a_n$,设 $x$ 的最高位为第 $k$ 位,那么在 $a_1,a_2,⋯,a_n$ 中,一定有一个值的第 $k$ 位为 $1$。
+
+设该值为 $a_i$,那么由于 $x$ 的第 $k$位和 $a_i$ 的第 $k$ 位都是 $1$,且第 $k$ 位是 $x$ 的最高位,所以 $a_i XOR x$ 一定小于 $a_i$
+
+又因为 $a_i$ 是其中一个棋子所在点的 $SG$ 函数值,那么根据 $SG$ 函数值的定义,该点能到达的所有点中,一定存在一个点的 $SG$ 函数值为 $a_i XOR x$
+
+那么我们就可以将该点上的棋子,移到一个 $SG$ 函数值为 $a_i XOR x$ 的点上去
+
+移完之后,原来每个棋子所在点的 $SG$ 函数异或值就变为了 $a_1 XOR a_2 XOR ⋯ XOR a_{i−1} XOR (a_i XOR x) XOR a_{i+1} ⋯ XOR a_n$
+
+$=(a_1 XOR a_2 XOR ⋯ XOR a_n) XOR x=x XOR x=0$
+
+① 证毕
+
+
+**证明** $2$:
+反证法,设将点 $u$ 上的棋子移动到点 $v$ 上后,每个棋子所在点的 $SG$ 函数值仍然为 $0$
+那就说明 $SG(u)=SG(v)$,不符合 $SG$ 函数的定义,不成立
+② 证毕
+
+所以做法是正确的。
+
+那么如何求出每个点的 $SG$ 函数值呢?
+记忆化搜索就好啦~
+每层记忆化搜索中,如果该点的 $SG$ 函数值已经被计算出,那就直接返回该值。否则用一个 $set$ 记录每个点能到的所有点的 $SG$ 函数值集合,然后从 $0$ 开始遍历,找到第一个 $set$ 里面没有的数,将该值记录在该点上并返回。
+
+
+#### 3、回到本题
- 如果只有一个棋子(棋子位置是$s$):
先手必胜 $\Leftrightarrow $ `sg(s)!=0`
From ca23979c24b00b525c4e0c8ea891f336b6df4b03 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=84=E6=B5=B7?= <10402852@qq.com>
Date: Mon, 25 Dec 2023 14:26:16 +0800
Subject: [PATCH 06/87] 'commit'
---
TangDou/AcWing_TiGao/T5/GameTheory/1319.md | 24 +++++++++-------------
1 file changed, 10 insertions(+), 14 deletions(-)
diff --git a/TangDou/AcWing_TiGao/T5/GameTheory/1319.md b/TangDou/AcWing_TiGao/T5/GameTheory/1319.md
index a2adede..c707378 100644
--- a/TangDou/AcWing_TiGao/T5/GameTheory/1319.md
+++ b/TangDou/AcWing_TiGao/T5/GameTheory/1319.md
@@ -53,7 +53,8 @@ win
如图:
-例图解释:
+**例图解释**:
+
$SG(5)=mex({\phi})=0$
$SG(3)=mex({SG(5)})=mex({0})=1$
$SG(4)=mex({SG(5),SG(3)})=mex({0,1})=2$
@@ -67,7 +68,9 @@ $SG(1)=mex({SG(2),SG(4)})=mex({0,2})=1$
**证明**:
首先,由于这是一张有向无环图,所以游戏最后一定会结束,也就是说每个棋子最后都会移动到一个点上,且该点没有任何能到达的点。
-那么根据定义,结束状态的所有点的 $SG$ 函数值异或起来为 $0$,做法对于结束状态可行。
+
+根据定义,结束状态的所有点的 $SG$ 函数值异或起来为 $0$,**做法对于结束状态可行**。
+
所以接下来,只要证明出
- ① 任何一种每个棋子所在点的 $SG$ 函数值异或起来非 $0$ 的情况,一定能通过一次移动棋子,到达一个 每个棋子所在点的 $SG$ 函数值异或起来为 $0$ 的情况
@@ -79,15 +82,15 @@ $SG(1)=mex({SG(2),SG(4)})=mex({0,2})=1$
**证明** $1$:
设每个棋子所在点的 $SG$ 函数值分别为 $a_1,a_2,⋯,a_n$
-设 $x=a_1 XOR a_2 XOR ⋯ XOR a_n$,设 $x$ 的最高位为第 $k$ 位,那么在 $a_1,a_2,⋯,a_n$ 中,一定有一个值的第 $k$ 位为 $1$。
-
-设该值为 $a_i$,那么由于 $x$ 的第 $k$位和 $a_i$ 的第 $k$ 位都是 $1$,且第 $k$ 位是 $x$ 的最高位,所以 $a_i XOR x$ 一定小于 $a_i$
+设 $x=a_1 XOR a_2 XOR ⋯ XOR a_n$,**此时$x$一定不等于$0$**。
+设 $x$ 的最高位为第 $k$ 位,那么在 $a_1,a_2,⋯,a_n$ 中,一定有一个值的第 $k$ 位为 $1$。
+设该值为 $a_i$,那么由于 $x$ 的第 $k$位和 $a_i$ 的第 $k$ 位都是 $1$,且,第 $k$ 位是 $x$ 的最高位,所以 $a_i XOR x$ 一定小于 $a_i$
又因为 $a_i$ 是其中一个棋子所在点的 $SG$ 函数值,那么根据 $SG$ 函数值的定义,该点能到达的所有点中,一定存在一个点的 $SG$ 函数值为 $a_i XOR x$
那么我们就可以将该点上的棋子,移到一个 $SG$ 函数值为 $a_i XOR x$ 的点上去
-移完之后,原来每个棋子所在点的 $SG$ 函数异或值就变为了 $a_1 XOR a_2 XOR ⋯ XOR a_{i−1} XOR (a_i XOR x) XOR a_{i+1} ⋯ XOR a_n$
+**移完之后**,原来每个棋子所在点的 $SG$ 函数异或值就变为了 $a_1 XOR a_2 XOR ⋯ XOR a_{i−1} XOR (a_i XOR x) XOR a_{i+1} ⋯ XOR a_n$
$=(a_1 XOR a_2 XOR ⋯ XOR a_n) XOR x=x XOR x=0$
@@ -101,18 +104,11 @@ $=(a_1 XOR a_2 XOR ⋯ XOR a_n) XOR x=x XOR x=0$
所以做法是正确的。
-那么如何求出每个点的 $SG$ 函数值呢?
+#### 3、如何求出每个点的 $SG$ 函数值呢?
记忆化搜索就好啦~
每层记忆化搜索中,如果该点的 $SG$ 函数值已经被计算出,那就直接返回该值。否则用一个 $set$ 记录每个点能到的所有点的 $SG$ 函数值集合,然后从 $0$ 开始遍历,找到第一个 $set$ 里面没有的数,将该值记录在该点上并返回。
-#### 3、回到本题
-- 如果只有一个棋子(棋子位置是$s$):
-先手必胜 $\Leftrightarrow $ `sg(s)!=0`
-
-- 存在多个棋子(其实可以看成存在多个相同的棋盘,棋子的位置是$s_1,…,s_k$
-先手必胜 $\Leftrightarrow $ `sg(s1)^sg(s2)^...^sg(sk) != 0`
-
### 三、实现代码
```cpp {.line-numbers}
#include
From 3b645965d726e036f29f3adcb4c14c9afb71eb44 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=84=E6=B5=B7?= <10402852@qq.com>
Date: Mon, 25 Dec 2023 15:54:46 +0800
Subject: [PATCH 07/87] 'commit'
---
TangDou/AcWing_TiGao/T5/GameTheory/1321.md | 127 +++++----------------
1 file changed, 30 insertions(+), 97 deletions(-)
diff --git a/TangDou/AcWing_TiGao/T5/GameTheory/1321.md b/TangDou/AcWing_TiGao/T5/GameTheory/1321.md
index 8c4deee..a72bd71 100644
--- a/TangDou/AcWing_TiGao/T5/GameTheory/1321.md
+++ b/TangDou/AcWing_TiGao/T5/GameTheory/1321.md
@@ -1,7 +1,5 @@
##[$AcWing$ $1321$. 取石子](https://www.acwing.com/problem/content/description/1323/)
-**[参考题解](https://www.cnblogs.com/ZJXXCN/p/11068490.html)**
-
### 一、题目描述
$Alice$ 和 $Bob$ 两个好朋友又开始玩取石子了。
@@ -53,117 +51,52 @@ NO
必败态 $\Rightarrow$ 选择任何路线 $\Rightarrow$ 必胜态
-### 三、简单情况
-为什么会想到讨论简单情况呢?我们来思考一下:如果某一堆石子只有$1$个,随着我们执行拿走$1$个的操作,它的堆就没了,这样石子个数变了,堆数也变了,两个变量,问题变复杂了,我们上来就想难题,怕是搞不定。
-
-既然这样,我们就思考一下 **子空间** :只考虑所有个数大于等于$2$的那些堆,其它可能存在石子数等于$1$的,等我们想明白这个简单问题再研究扩展的事,由易到难。
-
-同时,我们需要思考博弈的胜负与什么因素相关呢?因为只有两种操作:**拿走一个石子、合并两堆**,很显然,**两个关键因素:石子个数、堆数**
-
-同时,两个操作同一时间只能执行一个,所以可以理解为拿走一个石子对结果影响一下,合并两堆石子对结果也是影响一下,初步考虑应该堆个数与石子总数的加法关系相关。
-
+### 三、本题题解
+先来考虑 **简单情况**:所有堆的石子个数 $>1$
-**子空间:当每堆的石子个数都是大于等于$2$时**
+设 $b$ = 堆数 + 石子总数 $− 1$
-设$b$ = 堆数 + 石子总数 - $1$
-结论:$b$是奇数⟺先手必胜,$b$是偶数⟺先手必败
+可以推出: **先手必胜 $\Leftrightarrow$ $b$是奇数**
-**证明:**
+**证明**:考虑以下结论:
-1、边界:当我们只有一堆石子且该堆石子个数为$1$个时,$b=1$,先手必胜。
+$α$. 任意一个是奇数的情况 **可以** 被转换成一个偶数的情况 (一定存在一个偶数后继)
-2、当$b$为奇数,一定可以通过某种操作将$b$变成偶数
-* 如果堆数大于$1$,合并两堆让$b$变为偶数
-* 如果堆数等于$1$,从该堆石子中取出一个就可以让$b$变为偶数
+$β$. 任意一个是偶数的情况 **一定** 会被转换成一个奇数的情况 (所有后继都是奇数)。
-3、当$b$为偶数,无论如何操作,$b$都必将变为奇数
-* 合并两堆,则$b$变为奇数
-* 从某一堆中取走一个石子:
- * 若该堆石子个数大于$2$,则$b$变为奇数,且所有堆石子数量严格大于$1$
- * 若该堆石子个数等于$2$,取一个石子后,$b$变为奇数,该堆石子个数变为$1$个,此时就再是子空间范围内了,因为出现某堆的石子个数为$1$,而不是每一堆都大于等于$2$了!需要继续分类讨论:
-
-#### 特殊情况
-此时为了保证所有堆的石子个数大于$1$,**足够聪明的对手** 可以进行的操作分为两类:
- ① 如果只有这一堆石子,此时 **对手必胜**
- ② 如果有多堆石子,可以将这一个石子合并到其他堆中,这样每对石子个数都大于$1$
-
- **$Q$:对手为什么一定要采用合并的操作,而不是从别的堆中取石子呢?**
- 我来举两个简单的栗子:
-
- * **只有一堆石子**
- 石子个数是$2$个。你拿走一个,对手直接拿走另一个,游戏结束,**对手赢了**!你也是足够聪明的,你会在这种情况下这么拿吗?不能吧~,啥时候可能遇到这个情况呢?就是你被 **逼到** 这个场景下,也就是一直处于必败态!
-
- * **两堆石子**
- 每堆石子个数是$2$个。**我是先手**,可以有两种选择:
-
- (1)、从任意一堆中拿走$1$个, 现在的局面是$\{2,1\}$
- $$\large 后手选择(对手) \Rightarrow
- \left\{\begin{matrix}
- 从2中取一个 & \Rightarrow \{1,1\} & \Rightarrow
- \large \left\{\begin{matrix}
- 先手合并 \Rightarrow \{2\}& 剩下一个一个取,先手胜 \\
- 先手后手一个一个取 \Rightarrow 先手败 &
- \end{matrix}\right.
- \\
- 从1中取一个& \Rightarrow \{2,0\} & 剩下一个一个取,先手败\\
- 合并两堆 & \Rightarrow \{3\} & 剩下一个一个取,先手胜 \\
- \end{matrix}\right.
- $$
- 指望对手出错我才有赢的机会,人家要是聪明,我就废了!
-
- 我是先手,我肯定不能把自己的命运交到别人手中!我选择合并两堆,这样我保准赢!
-
- (2)、把两堆直接合并,现在的状态$\{4\}$
- 这下进入了我的套路,你取吧,你取一个,我也取一个;你再取一个,我也再取一个,结果,没有了,**对手必败**。
-
- 上面的例子可能不能描述所有场景,我现在$b$是奇数,我在必胜态,我不会让自己陷入到$b$可能是偶数的状态中去,如果我选择了
- - 合并操作减少$1$个堆
- - 拿走操作减少$1$个石子
- 都会把$b-1$这个偶数态给对方
- 我不会傻到一个操作,即可能造成堆也变化,让石子个数也变化,这样就得看对方怎么选择了,而他还那么聪明,我不能犯这样的错误。
+先来考虑结论 $α.$
+- 如果堆数 $>1$,可以合并其中两堆石子,这样 $b$ 就会变成偶数
+- 如果堆数 $=1$,就可以拿掉 $1$ 个石子,这样 $b$ 也会变成偶数
-### 四、本题情况
-本题中可能存在一些堆的石子个数等于$1$:
-* 假设有$a$堆石子,其中每堆石子个数为$1$
-* 剩余堆的石子个数都严格大于$1$
+再来考虑结论 $β$.
+- 合并其中的两堆石子:显然,$b$ 会变成奇数
+- 取了一个石子:
+ (1) 取得堆中石子个数 $>2$:石子个数 $− 1$,$b$ 会变成奇数
+ (2) 取得堆中石子个数 $=2$:石子个数变成了 $1$(继续分情况讨论):
+ 1) 只有一堆:$b$ 是奇数,对手必胜
+ 2) 多于一堆:$b$ 是奇数,对手可以把剩下的一个石子放到其他的堆里面去,对手同样必胜
-根据这些数量大于$1$的堆的石子可以求出上述定义出的$b$,我们使用$f(a, b)$表示此时先手必胜还是必败,因为博弈论在本质上是可以递推的,我们可以想出起点,再想出递推关系,就可以递推得到更大数据情况下的递推值,也就是博弈论本质上是$dp$。
+这样,我们成功的证明除了: **先手必胜 $\Leftrightarrow $ ($b$ 是奇数)**
-
-相关疑问
-$Q1:$**情况**$3$**为什么是两个表达式?**
-答:
-①当右侧存在时,合并左边两堆石子,则右侧多出一堆石子,并且,石子个数增加$2$,也就是$b+=3$
+接下来考虑一般情况:有些堆的石子个数可能 $=1$
+假设石子个数 $=1$ 的堆数为 $a$,$b$ 仍然表示剩余石子的 **操作数**,即 (堆数 $+$ 石子总数 $− 1$)
+把所有石子分成两个区域,一区域的数量 $=1$ (对应 $a$),二区域的数量都 $>1$ (对应 $b$).
-②当右侧一个都没有的时候,左边送来了一堆,两个石子,按$b$的定义,是堆数+石子个数$-1=2$,即$b+=2$
+那么可以写出以下转移:
-$Q2$:**为什么用一个奇数来描述简单情况的状态,而不是用偶数呢?**
-答:因为要通过递推式进行计算,最终的边界是需要我们考虑的:
-
-- 如果用奇数,那么边界就是$b=1$,表示只有$1$堆,石子数量只有$1$个,此时当然必胜。
-
-- 如果用偶数,比如边界是$b=0$,表示目前$0$堆,$0$个石子,这都啥也没有了,还必胜态,不符合逻辑,说不清道不明。
-
-- 那要是不用$b=0$做边界,用$b=2$呢?表示只有$1$堆,石子数量只有$1$个,这个应该也是可以,但没有再仔细想了。
-
-$Q3:$**情况**$2$**从右边取一个石子,如果此时右侧存在某一堆中石子个数是$2$,取走$1$个后,变成了$1$,不就是右侧减少了一个堆,减少了两个石子,即$b-=3$;同时,此堆石子个数变为$1$,左侧个数$a+=1$,为什么没有看到这个状态变化呢?**
-
-答:这是因为聪明人不会从右侧某个石子数量大于$2$的堆中取走石子!
-
-看一下 **讨论简单情况** 中第$3$点后面的 **特殊情况**:
- - 如果右侧只有一堆,石子数量为$2$,拿走$1$个,剩$1$个,一堆一个,对方必胜,此为必败态
-
- - 如果右侧大于一堆,某一堆只有$2$个石子,拿走$1$个,剩$1$个,对手足够聪明,会采用右侧两堆合并的办法,此时 石子数量减$1$,堆数减$1$,对$b$的影响是减$2$,对$b$的奇偶性没有影响,换句话说,如果你现在处在必败态,你这么整完,还是必败态
-
-
-### 五、时间复杂度
-这里因为$a$最大取$50$,$b$最大取$50050$,因此计算这些状态的计算量为$2.5×10^6$,虽然有最多$100$次查询,但是这些状态每个只会计算一遍,因此不会超时。
+$f(a,b)$:
+
+① 从 $a$中取 $1$个 $→f(a−1,b)$
+② 从 $b$中取 $1$个 $→f(a,b−1)$
+③ 合并 $b$中的 $2$个 $→f(a,b−1)$
+④ 合并 $a$中 $2$个 ($b$堆石子数 $+2$,堆数 $+1$) $→f(a−2,b+3)$
+⑤ 合并 $a$中 $1$个 $b$中 $1$个 ($b$堆石子数 $+1$, $a$个数 $−1$)$→f(a−1,b+1)$
-### 六、实现代码
+#### $Code$
```cpp {.line-numbers}
#include
using namespace std;
From fb01e15e336f830dcd06c2eb6bc01a1e0d762c85 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=84=E6=B5=B7?= <10402852@qq.com>
Date: Mon, 25 Dec 2023 15:55:07 +0800
Subject: [PATCH 08/87] 'commit'
---
.../T5/GameTheory/{1321_1.cpp => 1321.cpp} | 0
TangDou/AcWing_TiGao/T5/GameTheory/1321_2.cpp | 45 -------------------
2 files changed, 45 deletions(-)
rename TangDou/AcWing_TiGao/T5/GameTheory/{1321_1.cpp => 1321.cpp} (100%)
delete mode 100644 TangDou/AcWing_TiGao/T5/GameTheory/1321_2.cpp
diff --git a/TangDou/AcWing_TiGao/T5/GameTheory/1321_1.cpp b/TangDou/AcWing_TiGao/T5/GameTheory/1321.cpp
similarity index 100%
rename from TangDou/AcWing_TiGao/T5/GameTheory/1321_1.cpp
rename to TangDou/AcWing_TiGao/T5/GameTheory/1321.cpp
diff --git a/TangDou/AcWing_TiGao/T5/GameTheory/1321_2.cpp b/TangDou/AcWing_TiGao/T5/GameTheory/1321_2.cpp
deleted file mode 100644
index e9e0c1c..0000000
--- a/TangDou/AcWing_TiGao/T5/GameTheory/1321_2.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-#include
-using namespace std;
-
-int nums[60];
-
-void process(int n) {
- int a = 0, b = -1;
- for (int i = 0; i < n; i++) {
- if (nums[i] == 1)
- a++;
- else
- b += nums[i] + 1;
- }
- if (a == 0 && b > 0) {
- if (b % 2)
- puts("YES");
- else
- puts("NO");
- }
- if (a > 0 && b > 2) {
- if (a % 2 || b % 2)
- puts("YES");
- else
- puts("NO");
- }
- if (a > 0 && b <= 2) {
- if (a % 3)
- puts("YES");
- else
- puts("NO");
- }
-}
-
-int main() {
- int t, n;
- cin >> t;
- while (t--) {
- memset(nums, 0, sizeof(nums));
- cin >> n;
- for (int i = 0; i < n; i++)
- cin >> nums[i];
- process(n);
- }
- return 0;
-}
\ No newline at end of file
From 9e69186301b53dacffa9057f5077967d1bd9a3e9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=84=E6=B5=B7?= <10402852@qq.com>
Date: Mon, 25 Dec 2023 16:17:15 +0800
Subject: [PATCH 09/87] 'commit'
---
TangDou/AcWing_TiGao/T5/GameTheory/1321.cpp | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/TangDou/AcWing_TiGao/T5/GameTheory/1321.cpp b/TangDou/AcWing_TiGao/T5/GameTheory/1321.cpp
index 84ce99a..adb76c0 100644
--- a/TangDou/AcWing_TiGao/T5/GameTheory/1321.cpp
+++ b/TangDou/AcWing_TiGao/T5/GameTheory/1321.cpp
@@ -10,7 +10,7 @@ int dfs(int a, int b) {
if (!a) return v = b % 2; // 奇数为先手必胜,偶数为先手必败
// 一般5个情况 + 1个特殊情况
-
+
// 特殊情况: 如果操作后出现b中只有一堆,且堆中石子个数为1
// 那么应该归入到a中,并且b为0
// 以下所有情况,如果能进入必败态,先手则必胜!
@@ -41,14 +41,13 @@ int main() {
while (T--) {
cin >> n;
int a = 0, b = 0;
- for (int i = 0; i < n; i++) {
+ for (int i = 0; i < n; i++) { // n堆石子
int x;
cin >> x;
- if (x == 1) a++;
- // b != 0时 加1堆 + 加x石子 = 原来的 + x + 1 (其实就是区别一开始的时候)
- // 当b != 0时, 我们往后加的delta
- // b == 0时 加1堆 + 加x石子 = 0 + 1 + x - 1 = x
- // 注意操作符优先级
+ if (x == 1) a++; // 每堆石子的数量
+ // b==0时 加1堆+加x石子=0 + 1+x-1=x
+ // b!=0时 加1堆+加x石子=原来的+x+1
+ // 偏移量是1个,在b=0时,需要考虑引入这个偏移量:-1,在b>0时,就不必再次考虑了
else
b += b ? x + 1 : x;
}
From bb796bcd904801ab11f86abaf21dd6c4487bef31 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=84=E6=B5=B7?= <10402852@qq.com>
Date: Mon, 25 Dec 2023 16:58:28 +0800
Subject: [PATCH 10/87] 'commit'
---
TangDou/AcWing_TiGao/T5/GameTheory/1321.md | 195 +++++++++++++++++----
1 file changed, 164 insertions(+), 31 deletions(-)
diff --git a/TangDou/AcWing_TiGao/T5/GameTheory/1321.md b/TangDou/AcWing_TiGao/T5/GameTheory/1321.md
index a72bd71..43dc7e6 100644
--- a/TangDou/AcWing_TiGao/T5/GameTheory/1321.md
+++ b/TangDou/AcWing_TiGao/T5/GameTheory/1321.md
@@ -51,52 +51,117 @@ NO
必败态 $\Rightarrow$ 选择任何路线 $\Rightarrow$ 必胜态
-### 三、本题题解
+### 三、简单情况
+为什么会想到讨论简单情况呢?我们来思考一下:如果某一堆石子只有$1$个,随着我们执行拿走$1$个的操作,它的堆就没了,这样石子个数变了,堆数也变了,两个变量,问题变复杂了,我们上来就想难题,怕是搞不定。
-先来考虑 **简单情况**:所有堆的石子个数 $>1$
+既然这样,我们就思考一下 **子空间** :只考虑所有个数大于等于$2$的那些堆,其它可能存在石子数等于$1$的,等我们想明白这个简单问题再研究扩展的事,由易到难。
-设 $b$ = 堆数 + 石子总数 $− 1$
+同时,我们需要思考博弈的胜负与什么因素相关呢?因为只有两种操作:**拿走一个石子、合并两堆**,很显然,**两个关键因素:石子个数、堆数**
-可以推出: **先手必胜 $\Leftrightarrow$ $b$是奇数**
+同时,两个操作同一时间只能执行一个,所以可以理解为拿走一个石子对结果影响一下,合并两堆石子对结果也是影响一下,初步考虑应该堆个数与石子总数的加法关系相关。
-**证明**:考虑以下结论:
-$α$. 任意一个是奇数的情况 **可以** 被转换成一个偶数的情况 (一定存在一个偶数后继)
-$β$. 任意一个是偶数的情况 **一定** 会被转换成一个奇数的情况 (所有后继都是奇数)。
+**子空间:当每堆的石子个数都是大于等于$2$时**
+设$b$ = 堆数 + 石子总数 - $1$
+结论:$b$是奇数⟺先手必胜,$b$是偶数⟺先手必败
-先来考虑结论 $α.$
-- 如果堆数 $>1$,可以合并其中两堆石子,这样 $b$ 就会变成偶数
-- 如果堆数 $=1$,就可以拿掉 $1$ 个石子,这样 $b$ 也会变成偶数
+**证明:**
-再来考虑结论 $β$.
-- 合并其中的两堆石子:显然,$b$ 会变成奇数
-- 取了一个石子:
- (1) 取得堆中石子个数 $>2$:石子个数 $− 1$,$b$ 会变成奇数
- (2) 取得堆中石子个数 $=2$:石子个数变成了 $1$(继续分情况讨论):
- 1) 只有一堆:$b$ 是奇数,对手必胜
- 2) 多于一堆:$b$ 是奇数,对手可以把剩下的一个石子放到其他的堆里面去,对手同样必胜
+1、边界:当我们只有一堆石子且该堆石子个数为$1$个时,$b=1$,先手必胜。
-这样,我们成功的证明除了: **先手必胜 $\Leftrightarrow $ ($b$ 是奇数)**
+2、当$b$为奇数,一定可以通过某种操作将$b$变成偶数
+* 如果堆数大于$1$,合并两堆让$b$变为偶数
+* 如果堆数等于$1$,从该堆石子中取出一个就可以让$b$变为偶数
+3、当$b$为偶数,无论如何操作,$b$都必将变为奇数
+* 合并两堆,则$b$变为奇数
+* 从某一堆中取走一个石子:
+ * 若该堆石子个数大于$2$,则$b$变为奇数,且所有堆石子数量严格大于$1$
+ * 若该堆石子个数等于$2$,取一个石子后,$b$变为奇数,该堆石子个数变为$1$个,此时就再是子空间范围内了,因为出现某堆的石子个数为$1$,而不是每一堆都大于等于$2$了!需要继续分类讨论:
-接下来考虑一般情况:有些堆的石子个数可能 $=1$
-假设石子个数 $=1$ 的堆数为 $a$,$b$ 仍然表示剩余石子的 **操作数**,即 (堆数 $+$ 石子总数 $− 1$)
-把所有石子分成两个区域,一区域的数量 $=1$ (对应 $a$),二区域的数量都 $>1$ (对应 $b$).
+#### 特殊情况
+此时为了保证所有堆的石子个数大于$1$,**足够聪明的对手** 可以进行的操作分为两类:
+ ① 如果只有这一堆石子,此时 **对手必胜**
+ ② 如果有多堆石子,可以将这一个石子合并到其他堆中,这样每对石子个数都大于$1$
+
+ **$Q$:对手为什么一定要采用合并的操作,而不是从别的堆中取石子呢?**
+ 我来举两个简单的栗子:
+
+ * **只有一堆石子**
+ 石子个数是$2$个。你拿走一个,对手直接拿走另一个,游戏结束,**对手赢了**!你也是足够聪明的,你会在这种情况下这么拿吗?不能吧~,啥时候可能遇到这个情况呢?就是你被 **逼到** 这个场景下,也就是一直处于必败态!
+
+ * **两堆石子**
+ 每堆石子个数是$2$个。**我是先手**,可以有两种选择:
+
+ (1)、从任意一堆中拿走$1$个, 现在的局面是$\{2,1\}$
+ $$\large 后手选择(对手) \Rightarrow
+ \left\{\begin{matrix}
+ 从2中取一个 & \Rightarrow \{1,1\} & \Rightarrow
+ \large \left\{\begin{matrix}
+ 先手合并 \Rightarrow \{2\}& 剩下一个一个取,先手胜 \\
+ 先手后手一个一个取 \Rightarrow 先手败 &
+ \end{matrix}\right.
+ \\
+ 从1中取一个& \Rightarrow \{2,0\} & 剩下一个一个取,先手败\\
+ 合并两堆 & \Rightarrow \{3\} & 剩下一个一个取,先手胜 \\
+ \end{matrix}\right.
+ $$
+ 指望对手出错我才有赢的机会,人家要是聪明,我就废了!
+
+ 我是先手,我肯定不能把自己的命运交到别人手中!我选择合并两堆,这样我保准赢!
+
+ (2)、把两堆直接合并,现在的状态$\{4\}$
+ 这下进入了我的套路,你取吧,你取一个,我也取一个;你再取一个,我也再取一个,结果,没有了,**对手必败**。
+
+ 上面的例子可能不能描述所有场景,我现在$b$是奇数,我在必胜态,我不会让自己陷入到$b$可能是偶数的状态中去,如果我选择了
+ - 合并操作减少$1$个堆
+ - 拿走操作减少$1$个石子
+ 都会把$b-1$这个偶数态给对方
-那么可以写出以下转移:
+ 我不会傻到一个操作,即可能造成堆也变化,让石子个数也变化,这样就得看对方怎么选择了,而他还那么聪明,我不能犯这样的错误。
-$f(a,b)$:
-
-① 从 $a$中取 $1$个 $→f(a−1,b)$
-② 从 $b$中取 $1$个 $→f(a,b−1)$
-③ 合并 $b$中的 $2$个 $→f(a,b−1)$
-④ 合并 $a$中 $2$个 ($b$堆石子数 $+2$,堆数 $+1$) $→f(a−2,b+3)$
-⑤ 合并 $a$中 $1$个 $b$中 $1$个 ($b$堆石子数 $+1$, $a$个数 $−1$)$→f(a−1,b+1)$
+### 四、本题情况
+本题中可能存在一些堆的石子个数等于$1$:
+* 假设有$a$堆石子,其中每堆石子个数为$1$
+* 剩余堆的石子个数都严格大于$1$
+
+根据这些数量大于$1$的堆的石子可以求出上述定义出的$b$,我们使用$f(a, b)$表示此时先手必胜还是必败,因为博弈论在本质上是可以递推的,我们可以想出起点,再想出递推关系,就可以递推得到更大数据情况下的递推值,也就是博弈论本质上是$dp$。
+
+
+
+相关疑问
+$Q1:$**情况**$3$**为什么是两个表达式?**
+答:
+①当右侧存在时,合并左边两堆石子,则右侧多出一堆石子,并且,石子个数增加$2$,也就是$b+=3$
+
+②当右侧一个都没有的时候,左边送来了一堆,两个石子,按$b$的定义,是堆数+石子个数$-1=2$,即$b+=2$
+
+$Q2$:**为什么用一个奇数来描述简单情况的状态,而不是用偶数呢?**
+答:因为要通过递推式进行计算,最终的边界是需要我们考虑的:
+
+- 如果用奇数,那么边界就是$b=1$,表示只有$1$堆,石子数量只有$1$个,此时当然必胜。
+- 如果用偶数,比如边界是$b=0$,表示目前$0$堆,$0$个石子,这都啥也没有了,还必胜态,不符合逻辑,说不清道不明。
-#### $Code$
+- 那要是不用$b=0$做边界,用$b=2$呢?表示只有$1$堆,石子数量只有$1$个,这个应该也是可以,但没有再仔细想了。
+
+$Q3:$**情况**$2$**从右边取一个石子,如果此时右侧存在某一堆中石子个数是$2$,取走$1$个后,变成了$1$,不就是右侧减少了一个堆,减少了两个石子,即$b-=3$;同时,此堆石子个数变为$1$,左侧个数$a+=1$,为什么没有看到这个状态变化呢?**
+
+答:这是因为聪明人不会从右侧某个石子数量大于$2$的堆中取走石子!
+
+看一下 **讨论简单情况** 中第$3$点后面的 **特殊情况**:
+ - 如果右侧只有一堆,石子数量为$2$,拿走$1$个,剩$1$个,一堆一个,对方必胜,此为必败态
+
+ - 如果右侧大于一堆,某一堆只有$2$个石子,拿走$1$个,剩$1$个,对手足够聪明,会采用右侧两堆合并的办法,此时 石子数量减$1$,堆数减$1$,对$b$的影响是减$2$,对$b$的奇偶性没有影响,换句话说,如果你现在处在必败态,你这么整完,还是必败态
+
+
+### 五、时间复杂度
+这里因为$a$最大取$50$,$b$最大取$50050$,因此计算这些状态的计算量为$2.5×10^6$,虽然有最多$100$次查询,但是这些状态每个只会计算一遍,因此不会超时。
+
+
+### 六、实现代码
```cpp {.line-numbers}
#include
using namespace std;
@@ -161,4 +226,72 @@ int main() {
}
return 0;
}
-```
\ No newline at end of file
+```
+
+思路: 我们可以简单猜想当总操作数
+∑
+a
+[
+i
+]
++
+n
+−
+1
+ 是奇数的时候,先手必胜。 但事实并非如此,有些情况并不成立 。 我们可以发现,当n是1的时候,这样结论显然成立。
+另外,我们还可以总结出当没有数量为1的石子堆时,这个结论也是成立的。 下面我们先来证明这个结论。
+
+猜想: 当没有数量为1的堆,上面和是奇数的时候,先手必胜,如果是偶数,先手必败。
+
+1. 先证明奇数必胜,对于先手来说,如果n>1,那么只要选两堆合并, 那么总操作数变成偶数,n=1明显只能选择减少1操作,后手还是偶数。对于后手来说,无论他是减少1,还是合并操作,留下的总操作数一定还是奇数。
+
+对于某些读者来说,可能会问,如果后手把某个2变成1,先手该怎么办,其实这个很容易操作,如果堆数超过1,先手一定选择合并这个数量为1的堆,如果只有一堆了而且还是1,明显先手必胜了。 所以,先手总是有办法让
+
+后手必败(操作数为偶数的局面),后手无论怎么走,都会让先手必胜(变成操作为奇数的局面),所以我们证明成立。
+
+2. 在上面,我们也证明了当操作数是偶数的时候,先手是必败的。
+
+
+
+接下来我们考虑有数量为1的堆的时候的情况,这个情况比较复杂,因为如果某个人把1减少1,那么这个堆同时也消失了,相当于操作数减少了2。
+
+由于数据规模不是很大,我们采用了动态规划的思想,用记忆化搜索来实现情况。
+
+f
+[
+a
+]
+[
+b
+]
+表示当数量为1的堆有a个,剩下的堆的操作数是b的时候,先手是必胜还是必败,
+f
+[
+a
+]
+[
+b
+]
+=
+1
+表示必胜,否则必败。b中不会出现数量为1的堆,除非只剩下一个堆了。
+
+情况1: 当a>=2的时候,合并两个数量为1的堆,这样就让b这边的操作数增加了2+(b>0),因为如果原来b大于0,相当于操作数增加了3,否则b原来是0,那么操作是只增加2.
+
+情况2: 和a>0 并且b>0 的时候,我们可以合并一个数量为1的堆和b中一个数量不为1的堆,那么a减少1,b增加1
+
+情况3:b>=2,我们合并b里面的两个堆或者减少1,无论哪种,都是让b里面的操作数减少1。
+
+情况4: 当a>0的时候,我们可以减少一个数量为1的堆,这样a就减少1,b不变。
+
+
+
+另外有一种非常特殊的情况,就是b等于1了,刚才我们说了,b里面不会出现数量为1的堆,除非只剩下一个堆了。因为b里面只要堆的数量超过1,就一定可以用合并超过替代减少1操作,这样是等价的。
+
+除非b里面只有一个堆了,那么我们就只能不断减少1了。
+
+所以当b是1的时候,实际我们求的问题应该变成f[a+1][0]
+
+
+
+以上内容是我自己的一个总结,网上有些题解感觉写的不是很清楚,我自己理了一下思路,重新写了一个题解。
\ No newline at end of file
From f34248727840f31618832cd4c6c25e6f57b8097d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=84=E6=B5=B7?= <10402852@qq.com>
Date: Tue, 26 Dec 2023 08:02:15 +0800
Subject: [PATCH 11/87] 'commit'
---
TangDou/AcWing_TiGao/T5/GameTheory/1321.md | 107 +++------------------
1 file changed, 16 insertions(+), 91 deletions(-)
diff --git a/TangDou/AcWing_TiGao/T5/GameTheory/1321.md b/TangDou/AcWing_TiGao/T5/GameTheory/1321.md
index 43dc7e6..d812cb9 100644
--- a/TangDou/AcWing_TiGao/T5/GameTheory/1321.md
+++ b/TangDou/AcWing_TiGao/T5/GameTheory/1321.md
@@ -47,30 +47,32 @@ NO
### 二、博弈论总结
- 必胜态 $\Rightarrow$ 选择合适方案 $\Rightarrow$ 必败态
- 必败态 $\Rightarrow$ 选择任何路线 $\Rightarrow$ 必胜态
-
+ 必胜态 $\Rightarrow$ 选择合适方案 $\Rightarrow$ 对手必败态
+ 必败态 $\Rightarrow$ 选择任何路线 $\Rightarrow$ 对手必胜态
+
-### 三、简单情况
-为什么会想到讨论简单情况呢?我们来思考一下:如果某一堆石子只有$1$个,随着我们执行拿走$1$个的操作,它的堆就没了,这样石子个数变了,堆数也变了,两个变量,问题变复杂了,我们上来就想难题,怕是搞不定。
-
-既然这样,我们就思考一下 **子空间** :只考虑所有个数大于等于$2$的那些堆,其它可能存在石子数等于$1$的,等我们想明白这个简单问题再研究扩展的事,由易到难。
+ 对手聪明绝顶,不会犯错误,一旦他有机会获胜,他一定能找到合适的方案!所以,一定不能让他有机会,也就是总要让他总是处于必败状态,你才能获胜!
+
-同时,我们需要思考博弈的胜负与什么因素相关呢?因为只有两种操作:**拿走一个石子、合并两堆**,很显然,**两个关键因素:石子个数、堆数**
+### 三、思考过程
-同时,两个操作同一时间只能执行一个,所以可以理解为拿走一个石子对结果影响一下,合并两堆石子对结果也是影响一下,初步考虑应该堆个数与石子总数的加法关系相关。
+**$Q1$:本题中博弈的胜负与什么因素相关呢?**
+**答**:因为只有两种操作:**拿走一个石子、合并两堆**,很显然, 两个关键因素: **石子个数、堆数**
+**$Q2$:一般情况是什么,特殊情况是什么呢?**
+**答**:如果某一堆石子只有$1$个,随着我们执行拿走$1$个的操作,它的堆就没了,这样石子个数变了,堆数也变了,一下变两个,问题变复杂了,上来就想难题,怕是搞不定。
+既然这样,我们就思考一下 **一般情况** :只考虑所有个数大于等于$2$的那些堆,其它可能存在石子数等于$1$的,等我们想明白这个一般情况问题再研究特殊情况的事,由易到难。
+**$Q3$:猜一下关联关系?**
+两个操作同一时间只能执行一个,可以理解为拿走一个石子对结果影响一下,合并两堆石子对结果也是影响一下,初步考虑应该堆个数与石子总数的加法关系相关。
-**子空间:当每堆的石子个数都是大于等于$2$时**
+**一般情况:当每堆的石子个数都是大于等于$2$时,猜的关联关系**
设$b$ = 堆数 + 石子总数 - $1$
结论:$b$是奇数⟺先手必胜,$b$是偶数⟺先手必败
**证明:**
-
-1、边界:当我们只有一堆石子且该堆石子个数为$1$个时,$b=1$,先手必胜。
-
+1、**特殊情况**:当我们只有一堆石子且该堆石子个数为$1$个时,$b=1$,先手必胜。
2、当$b$为奇数,一定可以通过某种操作将$b$变成偶数
* 如果堆数大于$1$,合并两堆让$b$变为偶数
* 如果堆数等于$1$,从该堆石子中取出一个就可以让$b$变为偶数
@@ -138,16 +140,7 @@ $Q1:$**情况**$3$**为什么是两个表达式?**
②当右侧一个都没有的时候,左边送来了一堆,两个石子,按$b$的定义,是堆数+石子个数$-1=2$,即$b+=2$
-$Q2$:**为什么用一个奇数来描述简单情况的状态,而不是用偶数呢?**
-答:因为要通过递推式进行计算,最终的边界是需要我们考虑的:
-
-- 如果用奇数,那么边界就是$b=1$,表示只有$1$堆,石子数量只有$1$个,此时当然必胜。
-
-- 如果用偶数,比如边界是$b=0$,表示目前$0$堆,$0$个石子,这都啥也没有了,还必胜态,不符合逻辑,说不清道不明。
-
-- 那要是不用$b=0$做边界,用$b=2$呢?表示只有$1$堆,石子数量只有$1$个,这个应该也是可以,但没有再仔细想了。
-
-$Q3:$**情况**$2$**从右边取一个石子,如果此时右侧存在某一堆中石子个数是$2$,取走$1$个后,变成了$1$,不就是右侧减少了一个堆,减少了两个石子,即$b-=3$;同时,此堆石子个数变为$1$,左侧个数$a+=1$,为什么没有看到这个状态变化呢?**
+$Q2:$**情况**$2$**从右边取一个石子,如果此时右侧存在某一堆中石子个数是$2$,取走$1$个后,变成了$1$,不就是右侧减少了一个堆,减少了两个石子,即$b-=3$;同时,此堆石子个数变为$1$,左侧个数$a+=1$,为什么没有看到这个状态变化呢?**
答:这是因为聪明人不会从右侧某个石子数量大于$2$的堆中取走石子!
@@ -227,71 +220,3 @@ int main() {
return 0;
}
```
-
-思路: 我们可以简单猜想当总操作数
-∑
-a
-[
-i
-]
-+
-n
-−
-1
- 是奇数的时候,先手必胜。 但事实并非如此,有些情况并不成立 。 我们可以发现,当n是1的时候,这样结论显然成立。
-另外,我们还可以总结出当没有数量为1的石子堆时,这个结论也是成立的。 下面我们先来证明这个结论。
-
-猜想: 当没有数量为1的堆,上面和是奇数的时候,先手必胜,如果是偶数,先手必败。
-
-1. 先证明奇数必胜,对于先手来说,如果n>1,那么只要选两堆合并, 那么总操作数变成偶数,n=1明显只能选择减少1操作,后手还是偶数。对于后手来说,无论他是减少1,还是合并操作,留下的总操作数一定还是奇数。
-
-对于某些读者来说,可能会问,如果后手把某个2变成1,先手该怎么办,其实这个很容易操作,如果堆数超过1,先手一定选择合并这个数量为1的堆,如果只有一堆了而且还是1,明显先手必胜了。 所以,先手总是有办法让
-
-后手必败(操作数为偶数的局面),后手无论怎么走,都会让先手必胜(变成操作为奇数的局面),所以我们证明成立。
-
-2. 在上面,我们也证明了当操作数是偶数的时候,先手是必败的。
-
-
-
-接下来我们考虑有数量为1的堆的时候的情况,这个情况比较复杂,因为如果某个人把1减少1,那么这个堆同时也消失了,相当于操作数减少了2。
-
-由于数据规模不是很大,我们采用了动态规划的思想,用记忆化搜索来实现情况。
-
-f
-[
-a
-]
-[
-b
-]
-表示当数量为1的堆有a个,剩下的堆的操作数是b的时候,先手是必胜还是必败,
-f
-[
-a
-]
-[
-b
-]
-=
-1
-表示必胜,否则必败。b中不会出现数量为1的堆,除非只剩下一个堆了。
-
-情况1: 当a>=2的时候,合并两个数量为1的堆,这样就让b这边的操作数增加了2+(b>0),因为如果原来b大于0,相当于操作数增加了3,否则b原来是0,那么操作是只增加2.
-
-情况2: 和a>0 并且b>0 的时候,我们可以合并一个数量为1的堆和b中一个数量不为1的堆,那么a减少1,b增加1
-
-情况3:b>=2,我们合并b里面的两个堆或者减少1,无论哪种,都是让b里面的操作数减少1。
-
-情况4: 当a>0的时候,我们可以减少一个数量为1的堆,这样a就减少1,b不变。
-
-
-
-另外有一种非常特殊的情况,就是b等于1了,刚才我们说了,b里面不会出现数量为1的堆,除非只剩下一个堆了。因为b里面只要堆的数量超过1,就一定可以用合并超过替代减少1操作,这样是等价的。
-
-除非b里面只有一个堆了,那么我们就只能不断减少1了。
-
-所以当b是1的时候,实际我们求的问题应该变成f[a+1][0]
-
-
-
-以上内容是我自己的一个总结,网上有些题解感觉写的不是很清楚,我自己理了一下思路,重新写了一个题解。
\ No newline at end of file
From f75598f49dfbcffa85e5fc946e49e20963739dbe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=84=E6=B5=B7?= <10402852@qq.com>
Date: Tue, 26 Dec 2023 08:15:23 +0800
Subject: [PATCH 12/87] 'commit'
---
TangDou/AcWing_TiGao/T5/GameTheory/1321.md | 96 ++++++----------------
1 file changed, 26 insertions(+), 70 deletions(-)
diff --git a/TangDou/AcWing_TiGao/T5/GameTheory/1321.md b/TangDou/AcWing_TiGao/T5/GameTheory/1321.md
index d812cb9..a8dca4e 100644
--- a/TangDou/AcWing_TiGao/T5/GameTheory/1321.md
+++ b/TangDou/AcWing_TiGao/T5/GameTheory/1321.md
@@ -71,87 +71,43 @@ NO
设$b$ = 堆数 + 石子总数 - $1$
结论:$b$是奇数⟺先手必胜,$b$是偶数⟺先手必败
-**证明:**
-1、**特殊情况**:当我们只有一堆石子且该堆石子个数为$1$个时,$b=1$,先手必胜。
-2、当$b$为奇数,一定可以通过某种操作将$b$变成偶数
-* 如果堆数大于$1$,合并两堆让$b$变为偶数
-* 如果堆数等于$1$,从该堆石子中取出一个就可以让$b$变为偶数
-
-3、当$b$为偶数,无论如何操作,$b$都必将变为奇数
-* 合并两堆,则$b$变为奇数
-* 从某一堆中取走一个石子:
- * 若该堆石子个数大于$2$,则$b$变为奇数,且所有堆石子数量严格大于$1$
- * 若该堆石子个数等于$2$,取一个石子后,$b$变为奇数,该堆石子个数变为$1$个,此时就再是子空间范围内了,因为出现某堆的石子个数为$1$,而不是每一堆都大于等于$2$了!需要继续分类讨论:
-
-#### 特殊情况
-此时为了保证所有堆的石子个数大于$1$,**足够聪明的对手** 可以进行的操作分为两类:
- ① 如果只有这一堆石子,此时 **对手必胜**
- ② 如果有多堆石子,可以将这一个石子合并到其他堆中,这样每对石子个数都大于$1$
-
- **$Q$:对手为什么一定要采用合并的操作,而不是从别的堆中取石子呢?**
- 我来举两个简单的栗子:
-
- * **只有一堆石子**
- 石子个数是$2$个。你拿走一个,对手直接拿走另一个,游戏结束,**对手赢了**!你也是足够聪明的,你会在这种情况下这么拿吗?不能吧~,啥时候可能遇到这个情况呢?就是你被 **逼到** 这个场景下,也就是一直处于必败态!
-
- * **两堆石子**
- 每堆石子个数是$2$个。**我是先手**,可以有两种选择:
-
- (1)、从任意一堆中拿走$1$个, 现在的局面是$\{2,1\}$
- $$\large 后手选择(对手) \Rightarrow
- \left\{\begin{matrix}
- 从2中取一个 & \Rightarrow \{1,1\} & \Rightarrow
- \large \left\{\begin{matrix}
- 先手合并 \Rightarrow \{2\}& 剩下一个一个取,先手胜 \\
- 先手后手一个一个取 \Rightarrow 先手败 &
- \end{matrix}\right.
- \\
- 从1中取一个& \Rightarrow \{2,0\} & 剩下一个一个取,先手败\\
- 合并两堆 & \Rightarrow \{3\} & 剩下一个一个取,先手胜 \\
- \end{matrix}\right.
- $$
- 指望对手出错我才有赢的机会,人家要是聪明,我就废了!
-
- 我是先手,我肯定不能把自己的命运交到别人手中!我选择合并两堆,这样我保准赢!
-
- (2)、把两堆直接合并,现在的状态$\{4\}$
- 这下进入了我的套路,你取吧,你取一个,我也取一个;你再取一个,我也再取一个,结果,没有了,**对手必败**。
-
- 上面的例子可能不能描述所有场景,我现在$b$是奇数,我在必胜态,我不会让自己陷入到$b$可能是偶数的状态中去,如果我选择了
- - 合并操作减少$1$个堆
- - 拿走操作减少$1$个石子
- 都会把$b-1$这个偶数态给对方
+我们可以发现,当$n$是$1$的时候,这样结论显然成立。
- 我不会傻到一个操作,即可能造成堆也变化,让石子个数也变化,这样就得看对方怎么选择了,而他还那么聪明,我不能犯这样的错误。
+然后分类讨论:
-### 四、本题情况
-本题中可能存在一些堆的石子个数等于$1$:
-* 假设有$a$堆石子,其中每堆石子个数为$1$
-* 剩余堆的石子个数都严格大于$1$
+**情况$1$:没有数量为$1$的堆**
+
+先证明奇数必胜,对于先手来说,
+ - $n>1$, 那么 **只要选两堆合并**, 那么 **总操作数变成偶数**
+ - $n=1$, 明显只能选择减少$1$操作,后手还是偶数。
+
+对于后手来说,无论他是减少$1$,还是合并操作,留下的总操作数一定还是奇数。
+
+对于某些读者来说,可能会问,如果后手把某个$2$变成$1$,先手该怎么办,其实这个很容易操作,如果堆数超过$1$,先手一定选择合并这个数量为$1$的堆,如果只有一堆了而且还是$1$,明显先手必胜了。 所以,先手总是有办法让后手必败(操作数为偶数的局面),后手无论怎么走,都会让先手必胜(变成操作为奇数的局面),所以我们证明成立。
+
+在上面,我们也证明了当操作数是偶数的时候,先手是必败的。
+
-根据这些数量大于$1$的堆的石子可以求出上述定义出的$b$,我们使用$f(a, b)$表示此时先手必胜还是必败,因为博弈论在本质上是可以递推的,我们可以想出起点,再想出递推关系,就可以递推得到更大数据情况下的递推值,也就是博弈论本质上是$dp$。
+**情况$2$:有数量为$1$的堆**
-
+这个情况比较复杂,因为如果某个人把$1$减少$1$,那么这个堆同时也消失了,相当于操作数减少了$2$。
-相关疑问
-$Q1:$**情况**$3$**为什么是两个表达式?**
-答:
-①当右侧存在时,合并左边两堆石子,则右侧多出一堆石子,并且,石子个数增加$2$,也就是$b+=3$
+下面我们采用了动态规划的思想,用记忆化搜索来模拟演示一下:
-②当右侧一个都没有的时候,左边送来了一堆,两个石子,按$b$的定义,是堆数+石子个数$-1=2$,即$b+=2$
+$f[a][b]$ 表示当数量为$1$的堆有$a$个,剩下的堆的操作数是$b$的时候,先手是必胜还是必败,
+f[a][b]=1 表示必胜,否则必败。$b$中不会出现数量为$1$的堆,除非只剩下一个堆了。
-$Q2:$**情况**$2$**从右边取一个石子,如果此时右侧存在某一堆中石子个数是$2$,取走$1$个后,变成了$1$,不就是右侧减少了一个堆,减少了两个石子,即$b-=3$;同时,此堆石子个数变为$1$,左侧个数$a+=1$,为什么没有看到这个状态变化呢?**
+情况1: 当a>=2的时候,合并两个数量为1的堆,这样就让b这边的操作数增加了2+(b>0),因为如果原来b大于0,相当于操作数增加了3,否则b原来是0,那么操作是只增加2.
+情况2: 和a>0 并且b>0 的时候,我们可以合并一个数量为1的堆和b中一个数量不为1的堆,那么a减少1,b增加1
+情况3:b>=2,我们合并b里面的两个堆或者减少1,无论哪种,都是让b里面的操作数减少1。
+情况4: 当a>0的时候,我们可以减少一个数量为1的堆,这样a就减少1,b不变。
-答:这是因为聪明人不会从右侧某个石子数量大于$2$的堆中取走石子!
-看一下 **讨论简单情况** 中第$3$点后面的 **特殊情况**:
- - 如果右侧只有一堆,石子数量为$2$,拿走$1$个,剩$1$个,一堆一个,对方必胜,此为必败态
-
- - 如果右侧大于一堆,某一堆只有$2$个石子,拿走$1$个,剩$1$个,对手足够聪明,会采用右侧两堆合并的办法,此时 石子数量减$1$,堆数减$1$,对$b$的影响是减$2$,对$b$的奇偶性没有影响,换句话说,如果你现在处在必败态,你这么整完,还是必败态
+另外有一种非常特殊的情况,就是$b$等于$1$了,刚才我们说了,$b$里面不会出现数量为$1$的堆,除非只剩下一个堆了。因为$b$里面只要堆的数量超过$1$,就一定可以用合并超过替代减少$1$操作,这样是等价的。
+除非$b$里面只有一个堆了,那么我们就只能不断减少$1$了。
-### 五、时间复杂度
-这里因为$a$最大取$50$,$b$最大取$50050$,因此计算这些状态的计算量为$2.5×10^6$,虽然有最多$100$次查询,但是这些状态每个只会计算一遍,因此不会超时。
+所以当$b$是$1$的时候,实际我们求的问题应该变成$f[a+1][0]$
### 六、实现代码
From 8f454b820c2cd655fc7a691485513ee158304807 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=84=E6=B5=B7?= <10402852@qq.com>
Date: Tue, 26 Dec 2023 08:33:19 +0800
Subject: [PATCH 13/87] 'commit'
---
TangDou/AcWing_TiGao/T5/GameTheory/1321.md | 20 +++++++++-----------
1 file changed, 9 insertions(+), 11 deletions(-)
diff --git a/TangDou/AcWing_TiGao/T5/GameTheory/1321.md b/TangDou/AcWing_TiGao/T5/GameTheory/1321.md
index a8dca4e..759f309 100644
--- a/TangDou/AcWing_TiGao/T5/GameTheory/1321.md
+++ b/TangDou/AcWing_TiGao/T5/GameTheory/1321.md
@@ -92,22 +92,20 @@ NO
这个情况比较复杂,因为如果某个人把$1$减少$1$,那么这个堆同时也消失了,相当于操作数减少了$2$。
-下面我们采用了动态规划的思想,用记忆化搜索来模拟演示一下:
-$f[a][b]$ 表示当数量为$1$的堆有$a$个,剩下的堆的操作数是$b$的时候,先手是必胜还是必败,
-f[a][b]=1 表示必胜,否则必败。$b$中不会出现数量为$1$的堆,除非只剩下一个堆了。
+本题中可能存在一些堆的石子个数等于$1$:
+* 假设有$a$堆石子,其中每堆石子个数为$1$
+* 剩余堆的石子个数都严格大于$1$
-情况1: 当a>=2的时候,合并两个数量为1的堆,这样就让b这边的操作数增加了2+(b>0),因为如果原来b大于0,相当于操作数增加了3,否则b原来是0,那么操作是只增加2.
-情况2: 和a>0 并且b>0 的时候,我们可以合并一个数量为1的堆和b中一个数量不为1的堆,那么a减少1,b增加1
-情况3:b>=2,我们合并b里面的两个堆或者减少1,无论哪种,都是让b里面的操作数减少1。
-情况4: 当a>0的时候,我们可以减少一个数量为1的堆,这样a就减少1,b不变。
+根据这些数量大于$1$的堆的石子可以求出上述定义出的$b$,我们使用$f(a, b)$表示此时先手必胜还是必败,因为博弈论在本质上是可以递推的,我们可以想出起点,再想出递推关系,就可以递推得到更大数据情况下的递推值,也就是博弈论本质上是$dp$。
+
-另外有一种非常特殊的情况,就是$b$等于$1$了,刚才我们说了,$b$里面不会出现数量为$1$的堆,除非只剩下一个堆了。因为$b$里面只要堆的数量超过$1$,就一定可以用合并超过替代减少$1$操作,这样是等价的。
+$Q:$**情况**$3$**为什么是两个表达式?**
+答:
+①当右侧存在时,合并左边两堆石子,则右侧多出一堆石子,并且,石子个数增加$2$,也就是$b+=3$
-除非$b$里面只有一个堆了,那么我们就只能不断减少$1$了。
-
-所以当$b$是$1$的时候,实际我们求的问题应该变成$f[a+1][0]$
+②当右侧一个都没有的时候,左边送来了一堆,两个石子,按$b$的定义,是堆数+石子个数$-1=2$,即$b+=2$
### 六、实现代码
From 2c276652a10a633b9341468cd6aae6fe1c0d04be Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=84=E6=B5=B7?= <10402852@qq.com>
Date: Tue, 26 Dec 2023 10:53:00 +0800
Subject: [PATCH 14/87] 'commit'
---
TangDou/AcWing_TiGao/T5/GameTheory/1321.cpp | 75 +++++++------------
TangDou/AcWing_TiGao/T5/GameTheory/1321.eddx | Bin 0 -> 100485 bytes
TangDou/AcWing_TiGao/T5/GameTheory/1321.md | 17 +++--
3 files changed, 38 insertions(+), 54 deletions(-)
create mode 100644 TangDou/AcWing_TiGao/T5/GameTheory/1321.eddx
diff --git a/TangDou/AcWing_TiGao/T5/GameTheory/1321.cpp b/TangDou/AcWing_TiGao/T5/GameTheory/1321.cpp
index adb76c0..67a2816 100644
--- a/TangDou/AcWing_TiGao/T5/GameTheory/1321.cpp
+++ b/TangDou/AcWing_TiGao/T5/GameTheory/1321.cpp
@@ -1,59 +1,38 @@
-#include
+#include
+#include
using namespace std;
-const int N = 55, M = 50050; // M 包括了 50 * 1000 + 50个石子数量为1的堆数
-int f[N][M];
-
-int dfs(int a, int b) {
- int &v = f[a][b];
- if (~v) return v;
- // 简单情况: 即所有堆的石子个数都是严格大于1,此时a是0
- if (!a) return v = b % 2; // 奇数为先手必胜,偶数为先手必败
-
- // 一般5个情况 + 1个特殊情况
-
- // 特殊情况: 如果操作后出现b中只有一堆,且堆中石子个数为1
- // 那么应该归入到a中,并且b为0
- // 以下所有情况,如果能进入必败态,先手则必胜!
- if (b == 1) return dfs(a + 1, 0);
-
- // 情况1:有a,从a中取一个
- if (a && !dfs(a - 1, b)) return v = 1;
-
- // 情况2, 4:有b,从b中取1个(石子总数 - 1) or 合并b中两堆(堆数 - 1),
- if (b && !dfs(a, b - 1)) return v = 1;
-
- // 情况3:有a >= 2, 合并a中两个
- // 如果b的堆数不为0, a - 2, b + 1堆 + 2个石子(只需要加delta) ====> b + 3
- // 如果b的堆数为0, a - 2, 0 + 2个石子 + 1堆 - 1 ====> b + 2
- if (a >= 2 && !dfs(a - 2, b + (b ? 3 : 2))) return v = 1;
-
- // 情况5:有a,有b, 合并a中1个b中1个, a - 1, b的堆数无变化 + 1个石子(只加delta)
- if (a && b && !dfs(a - 1, b + 1)) return v = 1;
-
- // 其他情况,则先手处于必败状态
- return v = 0;
+const int N = 55, M = 50060;
+int n, f[N][M];
+int sg(int a, int b) {
+ if (f[a][b] != -1) return f[a][b];
+ int &s = f[a][b];
+ if (!a) return b & 1; // 如果能转移到必败态
+ if (b == 1) return sg(a + 1, b - 1);
+ if (a && !sg(a - 1, b)) return s = 1; // 取a
+ if (b && !sg(a, b - 1)) return s = 1; // 合并b,取b
+ if (a && b > 1 && !sg(a - 1, b + 1)) return s = 1; // 合并a,b
+ if (a > 1 && !sg(a - 2, b == 0 ? b + 2 : b + 3)) return s = 1; // 合并a
+ return s = 0;
}
-
int main() {
+ int T;
+ scanf("%d", &T);
memset(f, -1, sizeof f);
- int T, n;
- cin >> T;
+ f[1][0] = f[2][0] = 1;
+ f[3][0] = 0;
while (T--) {
- cin >> n;
- int a = 0, b = 0;
- for (int i = 0; i < n; i++) { // n堆石子
+ scanf("%d", &n);
+ int a = 0, b = -1;
+ for (int i = 1; i <= n; i++) {
int x;
- cin >> x;
- if (x == 1) a++; // 每堆石子的数量
- // b==0时 加1堆+加x石子=0 + 1+x-1=x
- // b!=0时 加1堆+加x石子=原来的+x+1
- // 偏移量是1个,在b=0时,需要考虑引入这个偏移量:-1,在b>0时,就不必再次考虑了
+ scanf("%d", &x);
+ if (x == 1)
+ a++;
else
- b += b ? x + 1 : x;
+ b += x + 1;
}
-
- // 1 为先手必胜, 0为先手必败
- if (dfs(a, b))
+ if (b < 0) b = 0;
+ if (sg(a, b))
puts("YES");
else
puts("NO");
diff --git a/TangDou/AcWing_TiGao/T5/GameTheory/1321.eddx b/TangDou/AcWing_TiGao/T5/GameTheory/1321.eddx
new file mode 100644
index 0000000000000000000000000000000000000000..e5f68389b6a60f37d745a09ec53070320a1e15e1
GIT binary patch
literal 100485
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