📅  最后修改于: 2023-12-03 14:58:37.198000             🧑  作者: Mango
题目链接:https://www.luogu.com.cn/problem/P1875
有一个大小为 $n \times m$ 的地图,每个格子上可能是 “#” 或者是 “.”。你要从左上角走到右下角,每一步只能向右或者往下走,且不能经过 “#” 的格子。请问有多少种不同的走法。
第一行包含 2 个整数 $n,m$,表示地图的大小。
接下来 $n$ 行,每行包含一个长度为 $m$ 的字符串,描述地图。
输出一个整数,表示可行的走法总数,答案对 $10^9+7$ 取模。
输入:
3 3
..#
...
#..
输出:
2
根据题目描述,可以使用动态规划求出解,具体做法如下:
设 $f(i,j)$ 表示从 $(1,1)$ 出发到 $(i,j)$ 的路径总数,那么可以得到状态转移方程为:
$$ f(i,j) = \begin{cases} f(i-1,j) + f(i,j-1),& (i,j) \text{为 "."} \ 0,& (i,j) \text{为 "#"} \end{cases} $$
边界条件为:
$$ f(1,1) = \begin{cases} 1,& (1,1) \text{为 "."} \ 0,& (1,1) \text{为 "#"} \end{cases} $$
最终的答案即为 $f(n,m)$,因为只能向右或向下走,所以最后一步要么从 $(n-1,m)$ 走到 $(n,m)$,要么从 $(n,m-1)$ 走到 $(n,m)$。
时间复杂度为 $O(nm)$。
完整代码如下(Python 版本):
MOD = 10**9+7
n, m = map(int, input().split())
# 初始化地图
g = []
for i in range(n):
g.append(list(input()))
# 初始化状态数组
f = [[0] * (m+1) for _ in range(n+1)]
f[1][1] = 1
# 状态转移
for i in range(1, n+1):
for j in range(1, m+1):
if g[i-1][j-1] == '.':
f[i][j] = (f[i-1][j] + f[i][j-1]) % MOD
print(f[n][m])
这里使用了 Python3 提供的多行输入和输入到二维列表的语法,具体解释可查阅 Python3 的官方文档。