Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.
Note: You can only move either down or right at any point in time.
假定gird用于保存m*n数字,
dp[i][j]表示到第i行第j列的最小路径和,则每次往右或者往下走,则得到递推公式
dp[i][j]=min(dp[i-1][j],dp[i][j-1])+grid[i][j]
初始值:
i=0,j=0 dp[i][j]=grid[i][j];
i=0,j>0 此时只能从左往右走,则dp[i][j]=dp[i][j-1]+grid[i][j];
i>0,j=0 此时只能从上往下走,则dp[i][j]=dp[i-1][j]+grid[i][j];
int minPathSum(vector<vector<int>>& grid) {
int m=grid.size();
if(m==0)
return -1;
int n=grid[0].size();
vector<vector<int> > dp(m,vector<int>(n));
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(i==0){
if(j==0){
dp[i][j]=grid[i][j];
}
else{
dp[i][j]=dp[i][j-1]+grid[i][j];
}
}
else{
if(j==0){
dp[i][j]=dp[i-1][j]+grid[i][j];
}
else{
dp[i][j]=min(dp[i-1][j],dp[i][j-1])+grid[i][j];
}
}
}
}
return dp[m-1][n-1];
}
优化空间
用一维数组代替二维数组,
由dp[i][j]=min(dp[i-1][j],dp[i][j-1])+grid[i][j] 知
dp[i][j]和dp[i-1][j],dp[i][j-1],grid[i][j]有关,这时如果计算顺序是正向,下标从小开始,
则在第i次循环,计算dp[j] 时,dp[i-1][j]可以看作是dp[j]的旧值,即第i-1次循环时的值,此时已经计算完成,dp[i][j-1]可以看作dp[j-1]
则可以更新为
dp[j]=min(dp[j-1],dp[j])+grid[i][j]
在代码中直接把dp[i][j] ==>dp[j] dp[i-1][j]==>dp[j]
vector<int> dp(n);
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(i==0){
if(j==0){
dp[j]=grid[i][j];
}
else{
dp[j]=dp[j-1]+grid[i][j];
}
}
else{
if(j==0){
dp[j]=dp[j]+grid[i][j];
}
else{
dp[j]=min(dp[j],dp[j-1])+grid[i][j];
}
}
}
}
return dp[n-1];