动态规划矩阵

简介: 动态规划矩阵

动态规划矩阵


接下来我们深入一下,看几道矩阵类型的题目:


62. 不同路径


一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。


机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。


问总共有多少条不同的路径?


对于每一个i,j都是到到第i-1,j和i,j-1位置的和

所以有dp[i][j]=dp[i1][j]+dp[i][j1]

class Solution {
public:
    int uniquePaths(int m, int n)
    {
        int dp[m][n];
        // 对于边界,到达路径只有1种可能
        for (int i = 0; i < m; i++) dp[i][0] = 1;
        for (int i = 0; i < n; i++) dp[0][i] = 1;
    
        for (int i = 1; i < m; i++)
        {
            for (int j = 1; j < n; j++)
            {
                dp[i][j] = dp[i-1][j] + dp[i][j-1];
            }
        }
        int cc = dp[m-1][n-1];
        return cc;
    }
};


64. 最小路径和


给定一个包含非负整数的 *m* x *n* 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。


**说明:**每次只能向下或者向右移动一步。


该题目和上面的题目有异曲同工之妙

class Solution {
public:
    int minPathSum(vector<vector<int>>& grid)
    {
        int n = grid.size(); int m = grid[0].size();
        int dp[n][m]; dp[0][0] = grid[0][0];
        for (int i = 1; i < n; i++) dp[i][0] = dp[i-1][0] + grid[i][0];
        for (int i = 1; i < m; i++) dp[0][i] = dp[0][i-1] + grid[0][i];
        for (int i = 1; i < n; i++) 
        {   
          for (int j = 1; j < m; j++) 
            {  
              dp[i][j]  = min(dp[i-1][j], dp[i][j-1]) + grid[i][j]; 
            }
        }
        return dp[n-1][m-1];
    }
};


63. 不同路径 II


一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。


机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”)。


现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?


网格中的障碍物和空位置分别用 10 来表示。


该题目是62的进阶版,有障碍物的位置设置为不可达即可

class Solution {
public:
    int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid)
    {
        int n = obstacleGrid.size();
        int m = obstacleGrid[0].size();
        int *f = new int[m];
        memset(f, 0, m * 4);
        f[0] = (obstacleGrid[0][0] == 0);

        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < m; j++)
            {
                if (obstacleGrid[i][j] == 1)
                {
                    f[j] = 0;
                    continue;
                }
                if (j -1 >=0 && obstacleGrid[i][j-1] == 0)
                {
                    f[j]+=f[j-1];
                }
            }
        }
        int val = f[m-1];
        delete [] f;
        return val;
    }
};


120. 三角形最小路径和


给定一个三角形 triangle ,找出自顶向下的最小路径和。


每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。也就是说,如果正位于当前行的下标 i ,那么下一步可以移动到下一行的下标 ii + 1

class Solution {
public:
    int minimumTotal(vector<vector<int>>& triangle)
    {
        int n = triangle.size();
        vector<vector<int>> f(n, vector<int>(n));
        f[0][0] = triangle[0][0];
        for (int i = 1; i < n; ++i) {
            f[i][0] = f[i - 1][0] + triangle[i][0];
            for (int j = 1; j < i; ++j) {
                f[i][j] = min(f[i - 1][j - 1], f[i - 1][j]) + triangle[i][j];
            }
            f[i][i] = f[i - 1][i - 1] + triangle[i][i];
        }
        return *min_element(f[n - 1].begin(), f[n - 1].end());
    }
};


931. 下降路径最小和


给你一个 n x n方形 整数数组 matrix ,请你找出并返回通过 matrix下降路径最小和

下降路径 可以从第一行中的任何元素开始,并从每一行中选择一个元素。在下一行选择的元素和当前行所选元素最多相隔一列(即位于正下方或者沿对角线向左或者向右的第一个元素)。具体来说,位置 (row, col) 的下一个元素应当是 (row + 1, col - 1)、(row + 1, col) 或者 (row + 1, col + 1) 。

class Solution {
public:
    int minFallingPathSum(vector<vector<int>>& matrix)
    {
        int n = matrix.size();
        vector<vector<int>> dp(n, vector<int>(n));
        // 初始化最初一行的dp
        copy(matrix[0].begin(), matrix[0].end(), dp[0].begin());
        // 推出之后的没一个下降
        // dp[i][j]=matrix[i][j]+min(dp[i−1][j−1],dp[i−1][j],dp[i−1][j+1])
        for (int i = 1; i < n; i++) {
            for (int j = 0; j < n; j++) {
                int mn = dp[i - 1][j];
                if (j > 0) {
                    mn = min(mn, dp[i - 1][j - 1]);
                }
                if (j < n - 1) {
                    mn = min(mn, dp[i - 1][j + 1]);
                }
                dp[i][j] = mn + matrix[i][j];
            }
        }
        return *min_element(dp[n - 1].begin(), dp[n - 1].end());
    }
};


221. 最大正方形


在一个由 '0''1' 组成的二维矩阵内,找到只包含 '1' 的最大正方形,并返回其面积。

class Solution {
public:
    int maximalSquare(vector<vector<char>>& matrix)
    {
        if (matrix.size() == 0 || matrix[0].size() == 0) return 0;

        int maxSide = 0;
        int rows = matrix.size(), columns = matrix[0].size();
        vector<vector<int>> dp(rows, vector<int>(columns));
        for (int i = 0; i < rows; ++i)
        {
            for (int j = 0; j < columns; j++)
            {
                if (matrix[i][j] == '1')
                {
                    if (i == 0 || j == 0)
                    {
                        dp[i][j] = 1;
                    }
                    else 
                    {
                        dp[i][j] = min(min(dp[i-1][j], dp[i][j-1]), dp[i-1][j-1]) + 1;
                    }
                    maxSide = max(maxSide, dp[i][j]);
                }
            }
        }
        int maxSquare = maxSide * maxSide;
        return maxSquare;
    }
};
目录
相关文章
|
4月前
leetcode-542:01 矩阵
leetcode-542:01 矩阵
17 0
|
9月前
|
人工智能 算法
动态规划之区间一维
噩梦中的仙境:动态规划之区间一维
37 0
动态规划之区间一维
|
12月前
|
人工智能
Leetcode53/152—最大子数组和/最大子数组乘积(状态转移方程/不熟)
Leetcode53/152—最大子数组和/最大子数组乘积(状态转移方程/不熟)
Leetcode动态规划篇(0-1背包问题一维和二维dp实现)
Leetcode动态规划篇(0-1背包问题一维和二维dp实现)
|
算法
秒懂算法 | 递推方程求解方法
时间复杂度和空间复杂度表示为递推方程的两种求解方法。
226 1
秒懂算法 | 递推方程求解方法
【动态规划篇】斐波那契数列&&拆分词句&&三角矩阵
【动态规划篇】斐波那契数列&&拆分词句&&三角矩阵
【动态规划篇】斐波那契数列&&拆分词句&&三角矩阵
|
人工智能 算法
【动态规划】矩阵连乘
完全加括号的矩阵连乘积可递归地定义为: • 单个矩阵是完全加括号的 • 矩阵连乘积A是完全加括号的,则A可表示为2个完全加括号的矩阵连乘积B和C 的乘积并加括号,即A=(BC) 设有四个矩阵A, B, C, D ,它们的维数分别是: A = 50*10 B = 10*40 C = 40*30 D = 30*5 总共有五种完全加括号的方式:
274 0
LeetCode 动态规划之矩阵区域和
LeetCode 动态规划之矩阵区域和
121 0
LeetCode 动态规划之矩阵区域和
|
算法 C语言 UED
[解题报告]【第35题】给定两个 a X b 和 c X d 的矩阵 ,求两个矩阵的乘积
[解题报告]【第35题】给定两个 a X b 和 c X d 的矩阵 ,求两个矩阵的乘积
|
机器学习/深度学习
【组合数学】递推方程 ( 递推方程示例 1 | 列出递推方程 )
【组合数学】递推方程 ( 递推方程示例 1 | 列出递推方程 )
109 0