1.不同路径
一个机器人位于一个 m*n 网格的左上角,机器人每次只能向下或者向右移动一步,机器人试图达到网格的右下角,问总共有多少条不同的路径?
示例如下:
到达每个格子的状态与他上面和左边格子有关,所以可以使用动态规划。
动态规划五部曲:
(1)dp数组和下标含义
dp[i][j] 表示为到(i,j)有多少条不同的路径。
(2)确定递归公式
dp[i][j] 只能通过dp[i-1][j]向下行走或dp[i][j-1]向右行走,所以dp[i][j] = dp[i-1][j] + dp[i][j-1]。
(3)dp数组初始化
第一行和第一列的数组均初始化为0。
(4)遍历顺序
从左往右一层一层遍历即可。这样可以保证推导dp[i][j]的时候,dp[i - 1][j] 和 dp[i][j - 1]一定是有数值的。
(5)举例推导dp数组
实现代码如下:
//不同的路径
int uniquePaths(int m, int n) {
//1.dp数组和下标含义
//到达dp[i][j]位置的路径个数
vector<vector<int>> dp(m, vector<int>(n,0));
//3.dp数组初始化
for(int i = 0; i<m; i++) {
dp[i][0] = 1;
}
for(int j = 0; j<n; j++) {
dp[0][j] = 1;
}
//4.遍历顺序
//2.确定递推公式
for(int i = 1; i < m; i++) {
for(int j = 1; j<n; j++) {
dp[i][j] = dp[i][j-1] + dp[i-1][j];
}
}
return dp[m-1][n-1];
//5.举例推导dp数组
}
2.不同路径II
与上一个类似,只是在赋值时要把障碍物处的dp[i][j]赋值为0,还有初始化时如果第一行或第一列出现障碍物需要把后面或下面的初始化为0,实现代码如下:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
int m = obstacleGrid.size();
int n = obstacleGrid[0].size();
//1.dp数组及下标含义
//dp[i][j]为到达(i,j)的路径
vector<vector<int>> dp(m, vector<int>(n,0));
//3.初始化
int index = -1;
for(int i = 0; i<m; i++) {
if(obstacleGrid[i][0] == 1) {
index = i;
}
if(index == -1) {
dp[i][0] = 1;
}
else if(index != -1) {
dp[i][0] = 0;
}
}
int index = -1;
for(int j = 0; i<n; j++) {
if(obstacleGrid[0][j] == 1) {
index = j;
}
if(index == -1) {
dp[0][j] = 1;
}
else if(index != -1) {
dp[0][j] = 0;
}
}
//4.遍历顺序
//2.递归公式
for(int i = 1; i<m; i++) {
for(int j = 1; j<n; j++) {
if(obstacleGrid[i-1][j] == 1) {
dp[i][j] = dp[i][j-1];
}
else if(obstacleGrid[i][j-1] == 1) {
dp[i][j] = dp[i-1][j];
}
else{
dp[i][j] = dp[i][j-1] + dp[i-1][j];
}
}
}
return dp[i-1][j-1];
//5.举例推导dp数组
}