题目描述
解题思路
前言:
解题的方法是用动态规划~
从数据范围可以看出,n、m最多就是200×200的大小,所以dp数组就开201
那么,怎么进行动态规划的求解呢?
由于路径的方向只能是向下或向右,因此网格的第一行的每个元素只能从左上角元素开始向右移动到达,网格的第一列的每个元素只能从左上角元素开始向下移动到达,此时的路径是唯一的,因此每个元素对应的最小路径和即为对应的路径上的数字总和。
对于不在第一行和第一列的元素,可以从其上方相邻元素向下移动一步到达,或者从其左方相邻元素向右移动一步到达,元素对应的最小路径和等于其上方相邻元素与其左方相邻元素两者对应的最小路径和中的最小值加上当前元素的值。由于每个元素对应的最小路径和与其相邻元素对应的最小路径和有关,因此可以使用动态规划求解。
对于边界处理:
对于dp[0][0] 当然就是 grid[0][0]了~~~
然后我们对第0行和第0列进行边界处理,注意 是从1开始就行了
行处理如下:
for(int j=1;j<m;j++) dp[0][j] = dp[0][j-1]+grid[0][j];
列处理如下:
for(int i=1;i<n;i++) dp[i][0] = dp[i-1][0]+grid[i][0];
中间递推的过程:
for(int i=1;i<n;i++)
for(int j=1;j<m;j++)
dp[i][j] = grid[i][j] + min(dp[i][j-1],dp[i-1][j]);
最后结果:
自然就是右下角的dp值
return dp[n-1][m-1];
解题代码:
class Solution {
public:
int minPathSum(vector<vector<int>>& grid) {
int n = grid.size(); //获取行数
int m = grid[0].size(); //获取列数
int dp[201][201] = {0};
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 j=1;j<m;j++) dp[0][j] = dp[0][j-1]+grid[0][j];
for(int i=1;i<n;i++)
for(int j=1;j<m;j++)
dp[i][j] = grid[i][j] + min(dp[i][j-1],dp[i-1][j]);
return dp[n-1][m-1];
}
};