From 1155284ae88ce39b70d94917f0ee5acd1228cadb 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 11:03:30 +0800 Subject: [PATCH] 'commit' --- TangDou/AcWing_TiGao/T5/GameTheory/1321.cpp | 45 ++++++++++++--------- TangDou/AcWing_TiGao/T5/GameTheory/1321.md | 6 +-- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/TangDou/AcWing_TiGao/T5/GameTheory/1321.cpp b/TangDou/AcWing_TiGao/T5/GameTheory/1321.cpp index 67a2816..7f6502d 100644 --- a/TangDou/AcWing_TiGao/T5/GameTheory/1321.cpp +++ b/TangDou/AcWing_TiGao/T5/GameTheory/1321.cpp @@ -1,38 +1,43 @@ -#include -#include +#include using namespace std; 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 dfs(int a, int b) { + if (~f[a][b]) return f[a][b]; // 记忆化搜索 + int &v = f[a][b]; // 引用,赋值更快捷 + if (!a) return b & 1; // a==0时,看b是不是奇数,奇数必胜,否则必败 + + if (b == 1) return dfs(a + 1, b - 1); + if (a && !dfs(a - 1, b)) return v = 1; // 从左边取一石子:左侧不空,并且取完后整体是一个必败态,那我必胜 + if (b && !dfs(a, b - 1)) return v = 1; // 合并b + if (a && b > 1 && !dfs(a - 1, b + 1)) return v = 1; // 合并a,b各一个 + if (a > 1 && !dfs(a - 2, b == 0 ? b + 2 : b + 3)) return v = 1; // 合并a + return v = 0; } int main() { int T; - scanf("%d", &T); - memset(f, -1, sizeof f); + cin >> T; + memset(f, -1, sizeof f); // 初始化DP数组,-1 + + // 边界初始化 f[1][0] = f[2][0] = 1; f[3][0] = 0; + while (T--) { - scanf("%d", &n); + cin >> n; int a = 0, b = -1; for (int i = 1; i <= n; i++) { int x; - scanf("%d", &x); + cin >> x; if (x == 1) - a++; + a++; // 左侧石子个数为1的石子堆数量 else - b += x + 1; + b += x + 1; // 1:新增加1堆,x:这一堆x个 } - if (b < 0) b = 0; - if (sg(a, b)) + if (b < 0) b = 0; // 一堆都没有,b=0 + + if (dfs(a, b)) puts("YES"); else puts("NO"); diff --git a/TangDou/AcWing_TiGao/T5/GameTheory/1321.md b/TangDou/AcWing_TiGao/T5/GameTheory/1321.md index e47be1e..e6d5553 100644 --- a/TangDou/AcWing_TiGao/T5/GameTheory/1321.md +++ b/TangDou/AcWing_TiGao/T5/GameTheory/1321.md @@ -105,12 +105,8 @@ NO
-$Q:$**情况**$3$**为什么是两个表达式?** -答: -①当右侧存在时,合并左边两堆石子,则右侧多出一堆石子,并且,石子个数增加$2$,也就是$b+=3$ - -②当右侧一个都没有的时候,左边送来了一堆,两个石子,按$b$的定义,是堆数+石子个数$-1=2$,即$b+=2$ +![](https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/BlogImages/202312261053532.png) ### 六、实现代码