[ARC157C] YY Square 题解

题意

  • 给出只含 XY 的矩阵,求出所有左上到右下的路径的权值 v 的平方和,定义 v 为路径上连续的两个 Y 的数量。

分析

  • 平方比较难搞定,考虑拆贡献。令 fx,y 表示到达坐标 (x,y) 时的平方和,假设有 l 条到达坐标 (x,y) 的路径,其权值分别为 v1,v2,,vl,那么就有

fx,y=i=1lvi2

  • mpx,y+1=mpx,y=Y(对于坐标 (x+1,y) 同理),则有转移

fx,y+1=i=1l(vi+1)2

展开得到

fx,y+1=fx,y+2i=1lvi+l

  • mpx,y+1mpx,y 之间存在 X,也就是说其构不成 YY 的结构,也就没有多余的贡献,那么直接转移即可。这里的 i=1lvi 很好维护,就是一般的 2 维 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;
}
posted @   HappyJaPhy  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示