描述
一个nxm的网格中,起点在(1,1),终点在(n,m),网格中有一块不能走的矩形区域,左下坐标为(x0,y0),右上坐标为(x1,y1),求从起点到终点的路径条数。
示例1
输入: 4,4,2,2,3,3 返回值: 2 说明: 只有两条可达路径
思路
这道题是求从起点到一个格子的所有路径。大家看上面的红点所在的格子,想要到红点所在的格子有两条路:一是:从红点左侧的格子过来;二是:从红点下侧的格子过来;然后我想要知道 红点 左侧格子有几条路径,也是用同样的方法。这样看来,我想求某个格子的路径数量应该是如下公式:
dp[m][n] = dp[m - 1][n] + dp[m][n - 1]; dp[m][n]: 某个格子的坐标; dp[m - 1][n]:是格子左侧的格子路径数量; dp[m][n - 1]:是格子下侧的格子路径数量;
这么就是动态规划的 状态转移方程。
动态规划除了状态转移方程还有一个重要的元素,那就是 初始值。
这道题的初始值很好确定,dp[1][1] = 1。就是起点位置默认是一条路径。
AC代码
public int GetNumberOfPath (int n, int m, int x0, int y0, int x1, int y1) {
// write code hereå
if (m < 1 || n < 1) {
return 0;
}
// 初始化dp数组
int[][] dp = new int[n + 1][m + 1];å
// 设置默认值
dp[1][1] = 1;
// 开始遍历所有格子
for (int i = 1; i <= n; i ++) {
for (int j = 1; j <= m; j ++) {
if (i == 1 && j == 1) {
continue;
}
// 当遇到不能走的区域 跳过
if (i >= x0 && i <= x1 && j >= y0 && j <= y1) continue;
// 每个格子的路径条数 = 左侧数量 + 下侧数量
dp[i][j] = (dp[i - 1][j] + dp[i][j - 1])%1000000007;
}
}
return dp[n][m];
} - 时间复杂度:O(m*n), m 和 n 分别是长宽,因为所有的格子都要遍历到。
- 空间复杂度:O(m*n),要将这些格子存储到 dp[m][n],二维数组中。
最后
更多的刷题已经知识,大家可以来我的博客看一看

京公网安备 11010502036488号