1. 最小路径和
题目链接:
64. 最小路径和 - 力扣(LeetCode)https://leetcode.cn/problems/minimum-path-sum/description/
2. 算法原理
状态表示:以莫一个位置位置为结尾
dp[i,j]表示:到达[i,j]位置的时候,此时的最小路径和
2. 状态转移方程
根据最近的一步来划分问题:
到达dp[i][j]有两种情况:
1. 从上面过来:[i-1,j] -> [i,j],dp[i-1,j] + g[i][j]
2. 从左边过来:[i,j-1] -> [i,j],dp[i,j-1] + g[i][j]
本题的状态转移方程是:dp[i][j] = min(dp[i-1,j] ,dp[i,j-1])+ g[i][j]
3. 初始化 :把dp表填满不越界,让后面的填表可以顺利进行
我们可以在上面的一行和左边的一列再额外的加上一行和一列的虚拟节点
初始化时可以先将所有的虚拟节点初始化为正无穷大,然后再把原始矩阵的第一个值的上方和左边的虚拟节点初始化为0,因为不能让虚拟节点的值干扰到原始矩阵节点的值
本题的下标映射关系:因为本题给了一个矩阵,而我们又额外的加上一行和一列的虚拟节点,所以我们的下标都统一往右下角移动了一位,如果想找回之前对应的位置,那么下标需要进行统一减1(横纵坐标)
4. 填表顺序
本题的填表顺序是:从上往下填写每一行,每一行的值是从左往右
5. 返回值 :题目要求 + 状态表示
本题的返回值是:dp[m][n]
3.代码
动态规划的固定四步骤:1. 创建一个dp表
2. 在填表之前初始化
3. 填表(填表方法:状态转移方程)
4. 确定返回值
class Solution {
public:
int minPathSum(vector<vector<int>>& grid) {
int m=grid.size(),n=grid[0].size();
//创建dp表随便将虚拟节点全部初始化为正无穷大
vector<vector<int>>dp(m+1,vector<int>(n+1,INT_MAX));
//再将dp[0][1]和dp[1][0]初始化为0
dp[0][1]=dp[1][0]=0;
for (int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++)
//这里的grid[i-1][j-1]也是加上一行和一列的虚拟节点,所以要横纵-1
dp[i][j]=min(dp[i - 1][j], dp[i][j - 1]) + grid[i - 1][j - 1];
return dp[m][n];
}
};
完结撒花~