2091F Div. 3 Round 1013
题意
一个 \(n \times m\) 的矩阵 , 其中有些点为X
现在一个人从最底层任意一个X位向上走到最顶层
规则:
-
每层最多过两个X , 最少过一个X
-
层间移动和层内移动都只能在X上走 , 且两个X的距离不超过 \(k\)
问有多少种走的可能
思路
动态规划
分析可知 , 设 \(a_{i,j}\) 表示第 \(i\) 层 , 第 \(j\) 个X的横坐标 , \(f_{i,a_{i,j}}\) 为到达第 \(i\) 层 , 横坐标为 \(a_{i,j}\) 的路径数
那么该处的路径有两种可能:
第一种是从同层左右转移而来 , 也就是 \([a_{i,j} - k , a_{i,j} + k]\) 区间内所有其他同层点
第二种是从上层转移过来 , 为\([a_{i,j} - k , a_{i,j} + k]\) 区间内所有其他上层点
首先应该计算哪个呢 ?
显然应该计算上层来的 , 然后计算同层转移的
此时可以发现实际上区间长度是固定的 , 因而双指针求解
需要注意 , 当计算同层点时会将自己覆盖 , 需要另外开一个数组储存
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long int
inline int read() {
int ans = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')f = -1;
ch = getchar();
}
while (ch <= '9' && ch >= '0') {
ans = ans * 10 + ch - '0';
ch = getchar();
}
return ans * f;
}
const int N =2005;
const int mod = 998244353;
int a[N][N],tmp[N];
char g[N][N];
int n, m ,dis,ds;
void lr(int row) {
memset(tmp, 0, sizeof tmp);
int sum = a[row][1];
int l = 1,r= 1;
for (int i =1; i<= m ; i++) {
if (g[row][i] !='X')
continue;
while (r + 1 <= m && r+1-i<=dis) {
sum += a[row][++r];
sum += mod;
sum %= mod;
}
while (i - l > dis) {
sum -= a[row][l++];
sum += mod;
sum %= mod;
}
tmp[i] = sum;
}
for (int i =1; i<= m; i++) {
a[row][i] = tmp[i];
}
return ;
}
void up(int row) {
int l = 1,r =1;
int sum = a[row][1];
for (int i =1; i<= m; i++) {
if (g[row-1][i] !='X')
continue;
while (r+1 <= m && r+1-i<=ds) {
sum += a[row][++r];
sum += mod;
sum %= mod;
}
while (i-l > ds) {
sum -= a[row][l++];
sum += mod;
sum %= mod;
}
a[row-1][i] = sum;
}
return ;
}
void solve() {
memset(a,0,sizeof a);
n =read(), m= read(),dis=read();
ds = (int) sqrt(dis * dis -1);
for (int i =1; i<= n; i++) {
for (int j =1; j<= m; j++) {
scanf("%c",&g[i][j]);
}
char ch = getchar();
}
for (int i =1; i<= m; i++) {
if (g[n][i] =='X')
a[n][i] = 1;
}
for (int i =n; i>=1; i--) {
lr(i);
if (i==1)
break;
up(i);
}
int ans =0 ;
for (int i =1; i<= m; i++) {
ans += a[1][i];
ans += mod;
ans %= mod;
}
cout<<ans<<"\n";
}
signed main() {
int t= read();
while (t--) solve();
return 0;
}

浙公网安备 33010602011771号