AC475A 2024省选联测26 博弈

cxqghzj·2024-02-26 19:41·14 次阅读

AC475A 2024省选联测26 博弈

题意#

两个人在一张 DAG 上移动棋子,每个格子的颜色为黑/白。

每次操作可以移动一个格子颜色和自己相同的棋子。

不能走的人输掉游戏。

先手为白色,问所有放棋子的 2n 种方案,先手必胜有多少。

Sol#

不难发现,自己颜色内的棋子不会被对方偷走,也就是说,想控制所有棋子使得对方判负,相当于比对方走到自己颜色多 k 步。

注意到对于每一个棋子放的格子来说,都有最优方案。

所以考虑算出每个棋子能对先手多多少步。

然后对这个做 0/1 背包即可。

注意负数情况。

Code#

Copy
#include <iostream> #include <algorithm> #include <cstdio> #include <array> #define int long long using namespace std; #ifdef ONLINE_JUDGE /* #define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++) */ /* char buf[1 << 23], *p1 = buf, *p2 = buf, ubuf[1 << 23], *u = ubuf; */ #endif int read() { int p = 0, flg = 1; char c = getchar(); while (c < '0' || c > '9') { if (c == '-') flg = -1; c = getchar(); } while (c >= '0' && c <= '9') { p = p * 10 + c - '0'; c = getchar(); } return p * flg; } void write(int x) { if (x < 0) { x = -x; putchar('-'); } if (x > 9) { write(x / 10); } putchar(x % 10 + '0'); } const int N = 305, M = 6e4 + 5, mod = 998244353; namespace G { array<int, N> fir; array<int, M> nex, to; int cnt = 1; void add(int x, int y) { cnt++; nex[cnt] = fir[x]; to[cnt] = y; fir[x] = cnt; } } // namespace G char strbuf[N]; array<int, N> f; void dfs(int x) { if (~f[x]) return; f[x] = 0; for (int i = G::fir[x]; i; i = G::nex[i]) { dfs(G::to[i]); if (strbuf[x] == 'W') f[x] = max(f[G::to[i]] + 1, f[x]); else f[x] = min(f[G::to[i]] - 1, f[x]); } } void Mod(int &x) { if (x >= mod) x -= mod; if (x < 0) x += mod; } array<int, 2 * N * N> g; signed main() { freopen("game.in", "r", stdin); freopen("game.out", "w", stdout); int n = read(), m = read(); scanf("%s", strbuf + 1); f.fill(-1); for (int i = 1; i <= m; i++) { int x = read(), y = read(); G::add(x, y); } for (int i = 1; i <= n; i++) dfs(i); g[n * n] = 1; for (int i = 1; i <= n; i++) if (f[i] >= 0) for (int j = 2 * n * n; j >= f[i]; j--) g[j] += g[j - f[i]], Mod(g[j]); else for (int j = 0; j <= 2 * n * n + f[i]; j++) g[j] += g[j - f[i]], Mod(g[j]); int ans = 0; for (int i = n * n + 1; i <= 2 * n * n; i++) ans += g[i], Mod(ans); write(ans), puts(""); return 0; }
posted @   cxqghzj  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示
目录