[ARC157C] YY Square 题解
题意
- 给出只含
X
和Y
的矩阵,求出所有左上到右下的路径的权值 的平方和,定义 为路径上连续的两个Y
的数量。
分析
- 平方比较难搞定,考虑拆贡献。令
表示到达坐标 时的平方和,假设有 条到达坐标 的路径,其权值分别为 ,那么就有
- 若
(对于坐标 同理),则有转移
展开得到
- 若
和 之间存在X
,也就是说其构不成YY
的结构,也就没有多余的贡献,那么直接转移即可。这里的 很好维护,就是一般的 维 DP,另外开一个 DP 数据来求即可。 - 上面推式子为了方便写的是主动转移,下面的代码用的是被动转移。
AC 代码
#include <bits/stdc++.h> #define int long long #define mod 998244353 #define N 2005 using namespace std; int n, m, cnt[N][N], f[N][N], f2[N][N], dv[2][2] = {{0, -1}, {-1, 0}}; bool mp[N][N]; char s[N]; signed main() { scanf("%lld%lld", &n, &m); for (int i = 1; i <= n; i++) { scanf("%s", s + 1); for (int j = 1; j <= m; j++) { if (s[j] == 'Y') mp[i][j] = 1; } } cnt[1][1] = 1; int x, y; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { if (i == 1 && j == 1) continue; for (int k = 0; k <= 1; k++) { x = i + dv[k][0], y = j + dv[k][1]; if (x < 1 || y < 1) continue; cnt[i][j] = (cnt[i][j] + cnt[x][y]) % mod; //转移路径数 if (mp[x][y] && mp[i][j]) { //都是 Y f[i][j] = (f[i][j] + f[x][y] + cnt[x][y]) % mod; //权值和 f2[i][j] = (f2[i][j] + f2[x][y] + (f[x][y] << 1ll) + cnt[x][y]) % mod; //权值平方和 } else { //存在 X f[i][j] = (f[i][j] + f[x][y]) % mod; f2[i][j] = (f2[i][j] + f2[x][y]) % mod; } } } } printf("%lld", f2[n][m]); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现