算法随想Day35【动态规划】| LC62-不同路径、LC63-不同路径Ⅱ

动态规划五部曲

  • 确定dp[i]的含义
  • dp递推公式
  • dp数组如何初始化
  • 确认dp数组遍历顺序
  • 打印dp数组,主要用于调试

LC62. 不同路径

  1. dp[i] [j]含义:到达格子(i, j)中有dp[i] [j]种方法
  2. 递推公式:dp[i] [j] = dp[i] [j - 1] + dp[i - 1] [j];
  3. dp数组初始化:dp[0] [0] = 1,最上一行和最左一列都初始化为1
  4. 确认dp数组遍历顺序:从左往右,从上往下

动态规划思想:坐标[m, n]是由[m, n - 1]向右或[m - 1, n]向下移动一步得来的

int uniquePaths(int m, int n)
{
    if (m == 1 || n == 1)
    {
        return 1;
    }
    vector<vector<int>> dp(m, vector<int>(n, 0));
    for (int i = 1; i < n; ++i)
    {
        dp[0][i] = 1;
    }
    for (int i = 1; i < m; ++i)
    {
        dp[i][0] = 1;
    }
    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];
}

LC63. 不同路径Ⅱ

与上一道题在数组初始化上,有点不同,在对最上一行和最左一列进行初始化时,一旦出现第一个障碍物,后面的格子(对最上一行来说是出现障碍物的格子及其右边的各自)都是不可达的,设置0

int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid)
{
    int row = obstacleGrid.size();
    int column = obstacleGrid[0].size();
    if(obstacleGrid[0][0] == 1)
    {
        return 0;
    } 
    if (row == 1 && column == 1 && obstacleGrid[0][0] == 0)
    {
            return 1;
    }
    vector<vector<int>> dp(row, vector<int>(column, 0));
    for (int i = 1; i < column; ++i)
    {
        if (obstacleGrid[0][i] == 1)
        {
            break;
        }
        dp[0][i] = 1;
    }
    for (int i = 1; i < row; ++i)
    {
        if (obstacleGrid[i][0] == 1)
        {
            break;
        }
        dp[i][0] = 1;
    }
    for (int i = 1; i < row; ++i)
    {
        for (int j = 1; j < column; ++j)
        {
            if (obstacleGrid[i][j] != 1)
            {
                dp[i][j] = dp[i][j - 1] + dp[i - 1][j];
            }
        }
    }
    return dp[row - 1][column - 1];
}
posted @ 2023-03-15 13:06  冥紫将  阅读(36)  评论(0)    收藏  举报