📅  最后修改于: 2023-12-03 15:41:20.484000             🧑  作者: Mango
在一个 $m\times n$ 的网格中,我们从其中一个点出发,可以向上、向下、向左或向右移动一格,但不能超出网格的边界。现在给定起点 $(i,j)$ 和终点 $(k,l)$,我们希望知道从起点到终点的所有路径数量。
这是一个典型的动态规划问题。设 $dp_{i,j}$ 表示从起点 $(i,j)$ 到当前位置 $(x,y)$ 的路径数量。则有:
$$ dp_{x,y} = dp_{x-1,y} + dp_{x+1,y} + dp_{x,y-1} + dp_{x,y+1} $$
其中,当 $x=1$ 时,$dp_{x-1,y}=0$,即起点不能向上移动;当 $x=m$ 时,$dp_{x+1,y}=0$,即终点不能向下移动;当 $y=1$ 时,$dp_{x,y-1}=0$,即起点不能向左移动;当 $y=n$ 时,$dp_{x,y+1}=0$,即终点不能向右移动。
最终,$dp_{k,l}$ 就是从起点到终点的路径数量。
def count_paths(m, n, i, j, k, l):
# 初始化 dp 数组
dp = [[0] * (n+1) for _ in range(m+1)]
dp[i][j] = 1
# 递推 dp 数组
for x in range(i, k+1):
for y in range(j, l+1):
if x == i and y == j:
continue
dp[x][y] = dp[x-1][y] + dp[x+1][y] + dp[x][y-1] + dp[x][y+1]
if x == 1:
dp[x-1][y] = 0
if x == m:
dp[x+1][y] = 0
if y == 1:
dp[x][y-1] = 0
if y == n:
dp[x][y+1] = 0
# 返回结果
return dp[k][l]
m = 3
n = 3
i = 1
j = 1
k = 3
l = 3
print(count_paths(m, n, i, j, k, l)) # 输出 6
以上代码的输出为 6,表示从起点 $(1,1)$ 到终点 $(3,3)$ 的路径数量为 6。