题目描述
牛牛有一个n*m的迷宫,对于迷宫中的每个格子都为’R’,‘D’,'B’三种类型之一,'R’表示处于当前的格子时只能往右边走’D’表示处于当前的格子时只能往下边走,而’B’表示向右向下均可以走。
我们认为迷宫最左上角的坐标为(1,1),迷宫右下角的坐标为(n,m),除了每个格子有向右移动以及向下移动的限制之外,你也不能够走出迷宫的边界。
牛牛现在想要知道从左上角走到右下角不同种类的走法共有多少种,请你告诉牛牛从(1,1)节点移动到(n,m)节点共有多少种不同的移动序列,请你输出方案数对 取余数后的结果。
我们认为两个移动序列是不同的,当且仅当移动序列的长度不同,或者在某一步中采取了不同的移动方式。
输入描述:
第一行输入两个正整数n,m(1 \leq n,m \leq 50)(1≤n,m≤50)表示迷宫的大小是n行m列。
接下来n行,每行输入一个长度为m的字符串,字符串中仅包含大写字母’D’,‘R’,‘B’。
输出描述:
输出一行一个整数,表示方案数对 取余数后的结果。
输入
5 5
RBBBR
BBBBB
BBBDB
BDBBB
RBBBB
输出
25
题解
- 经典的走格子DP
- 从左上角开始遍历,如果是D,就向下累加,如果是R就向右累加,如果是B同时累加就好
- 状态转移方程
-
AC-Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
const int maxn = 2e5 + 5;
const int mod = 1e9 + 7;
string mp[55];
ll dp[55][55];
int main() {
ios;
int n, m; while (cin >> n >> m) {
for (int i = 1; i <= n; ++i) {
cin >> mp[i];
mp[i] = " " + mp[i];
}
dp[1][1] = 1;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
if (mp[i][j] == 'R')
dp[i][j + 1] += (dp[i][j]) % mod;
else if (mp[i][j] == 'D')
dp[i + 1][j] += (dp[i][j]) % mod;
if (mp[i][j] == 'B') {
dp[i][j + 1] = (dp[i][j + 1] + dp[i][j]) % mod;
dp[i + 1][j] = (dp[i + 1][j] + dp[i][j]) % mod;
}
}
}
cout << dp[n][m] % mod << endl;
}
}