题目:931.下降路劲最小和
题目要求:
给你一个 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
解释:如图所示,为和最小的下降路径
这题可以用贪心,动态规划来解决;根据示例可知,某一个位置的最小路径和是由这个位置的上一行中左,中,中右和当前位置相加所得,第一行除外,第一行自己就是自己的最短路径和。
创建一个二维数组dp,其中dp[i][j]表示从第一行到第i行,以第i行第j列元素为结尾的下降路径的最小和。通过状态转移方程dp[i][j] = matrix[i][j] + min(dp[i-1][j-1], dp[i-1][j], dp[i-1][j+1])来计算每个位置的最小路径和。最后,在最后一行中找到最小路径和返回。
整体思路如下:
- 首先,我们可以观察到,每一行的下降路径的选择只依赖于上一行的下降路径的选择。
- 假设当前在第i行的第j列,那么下一行的下降路径可以选择第i+1行的第j列、第j-1列或第j+1列。
- 我们可以从第一行开始,依次计算每一行的下降路径的最小和。
- 对于第一行的每一个元素,它的下降路径的最小和就是它本身。
- 对于第二行及之后的每一行,我们可以通过选择上一行的下降路径的最小和来计算当前行的下降路径的最小和。
- 最后,我们只需要在最后一行中找到最小的下降路径的最小和即可。
具体实现的代码如下
class Solution {
public:
int minFallingPathSum(vector<vector<int>>& matrix) {
int n=matrix.size();
//定义dp数组,表示当前路径的最小和
vector<vector<int>> dp(n,vector<int>(n));
//初始化
dp[0]=matrix[0];
for(int i=1;i<n;i++){
for(int j=0;j<n;j++){
//当前路径等于上层位置加上本层位置
dp[i][j] = matrix[i][j]+dp[i-1][j];
if(j>0) //考虑左上角
dp[i][j] = min(dp[i][j],matrix[i][j]+dp[i-1][j-1]);
if(j<n-1) //考虑右上角
dp[i][j] = min(dp[i][j],matrix[i][j]+dp[i-1][j+1]);
}
}
int minS=INT_MAX;
//找出最后一行的最小路劲和
for(int i=0;i<n;i++){
minS=min(minS,dp[n-1][i]);
}
return minS;
}
};