题目:
思路:
每个点的dp只和上边和左边的最小值有关系,所以容易得出,状态方程为 dp[i][j] = min (dp[i-1][j] , dp[i][j-1]) + grid[i][j];
边界:最上面一行没有i-1,最左边一列没有j-1
代码:
class Solution {
public:
int minPathSum(vector<vector<int>>& grid) {
int dp[200][200],len1=grid[0].size(),len2=grid.size();
dp[0][0]=grid[0][0];
for(int i=1;i<len1;i++) dp[0][i]=dp[0][i-1]+grid[0][i]; //第一行
for(int i=1;i<len2;i++) dp[i][0]=dp[i-1][0]+grid[i][0]; //第一列
for(int i=1;i<len2;i++)
for(int j=1;j<len1;j++)
dp[i][j]=min(dp[i-1][j],dp[i][j-1])+grid[i][j];
return dp[len2-1][len1-1]; //最后一个数就是答案
}
};
内存还可以压缩,从状态方程中可以看出,dp只与左边和上边的dp有关系,所以可以只用一维数组。
状态转移方程: dp[j] = min (dp[j] , dp[j-1]) + grid[i][j];
代码(滚动数组):
class Solution {
public:
int minPathSum(vector<vector<int>>& grid) {
int dp[200],len1=grid[0].size(),len2=grid.size();
dp[0]=grid[0][0];
for(int i=1;i<len1;i++) dp[i]=dp[i-1]+grid[0][i]; //第一行
for(int i=1;i<len2;i++)
{
dp[0]=dp[0]+grid[i][0];
for(int j=1;j<len1;j++)
dp[j]=min(dp[j],dp[j-1])+grid[i][j];
}
return dp[len1-1];
}
};