1. 题目链接:931. 下降路径最小和
2. 题目描述:
给你一个
n x n
的 方形 整数数组matrix
,请你找出并返回通过matrix
的下降路径 的 最小和 。下降路径 可以从第一行中的任何元素开始,并从每一行中选择一个元素。在下一行选择的元素和当前行所选元素最多相隔一列(即位于正下方或者沿对角线向左或者向右的第一个元素)。具体来说,位置
(row, col)
的下一个元素应当是(row + 1, col - 1)
、(row + 1, col)
或者(row + 1, col + 1)
。示例 1:
输入:matrix = [[2,1,3],[6,5,4],[7,8,9]] 输出:13 解释:如图所示,为和最小的两条下降路径
示例 2:
输入:matrix = [[-19,57],[-40,-5]] 输出:-59 解释:如图所示,为和最小的下降路径
提示:
n == matrix.length == matrix[i].length
1 <= n <= 100
-100 <= matrix[i][j] <= 100
3. 解法(动态规划):
3.1算法思路:
3.1.1 状态表示:
dp[i][j]
表示:到达[i,j]
位置时,所有下降路径中的最小和
3.1.2 状态转移方程:
到达 [i,j]
位置可能有三种情况:
我们要的是三种情况下的最小值
,然后加上矩阵在[i,j]
位置
于是dp[i,j]=min(dp[i-1][j],min(dp[i-1][j-1],dp[i-1][j+1]))+matrix[i,j]
3.1.3 初始化
可以在最前面加上一个辅助结点,进行初始化。使用这种技巧需要注意两点:
-
辅助结点里面的值要保证后续填表是正确的
-
下标的映射关系
-
在本题中,需要加上一行,并且加上两列。所有位置都初始化为无穷大,然后将第一行初始化为
0
即可
3.1.4 填表顺序
从上往下
3.1.5 返回值
注意这里不是返回dp[m][n]
的值
题目要求:【只要到达最后一行】,因此这里应该返回【dp表
最后一行的最小值】
3.2 C++算法代码:
class Solution {
public:
int minFallingPathSum(vector<vector<int>>& matrix) {
int n=matrix.size();
//创建dp表
vector<vector<int>>dp(n+1,vector<int>(n+2,INT_MAX));
//初始化第一行
for(int j=0;j<n+2;j++) dp[0][j]=0;
//填表
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
dp[i][j]=min(dp[i-1][j-1],min(dp[i-1][j],dp[i-1][j+1]))+matrix[i-1][j-1];
}
}
int ret=INT_MAX;
for(int j=0;j<=n;j++)
{
ret=min(ret,dp[n][j]);
}
//返回结果
return ret;
}
};