1.描述
给定一个只含非负整数的m*n网格,找到一条从左上角到右下角的可以使数字和最小的路径。
注意事项
你在同一时间只能向下或者向右移动一步
2.分析
已经走到第i行第j个点时,判断是否可以向右或向下走,若都可以则取两者的小值。因此一般的状态转移方程为dp[i][j]+=min(dp[i+1][j],dp[i][j+1])。
3.代码
class Solution {
public:
/*
* @param grid: a list of lists of integers
* @return: An integer, minimizes the sum of all numbers along its path
*/
const int M=1000+5;
int minPathSum(vector<vector<int>> &grid) {
// write your code here
int dp[M][M];
int m=grid.size();
int n=grid[0].size();
dp[m][n]=grid[m-1][n-1];
for(int i=0;i<m;i++)//初始化dp数组
{
for(int j=0;j<n;j++)
{
dp[i+1][j+1]=grid[i][j];
}
}
for(int i=m;i>=1;i--)
{
for(int j=n;j>=1;j--)//从最右下角的数开始
{
if(i==m)//若为最后一行
{
if(j<n)//可以向右走
{
dp[i][j]+=dp[i][j+1];
}
}
else
{
if(j<n)//既不是最后一行也不是最后一列,即不是最右下角的元素
{
dp[i][j]+=min(dp[i+1][j],dp[i][j+1]);
//可以向下走也可以向右走,选小的走
}
else//若为最后一列,只能向下走。
{
dp[i][j]+=dp[i+1][j];
}
}
}
}
return dp[1][1];
}
};
4.总结
一般情况下根据状态转移方程dp[i][j]+=min(dp[i+1][j],dp[i][j+1])往下走就可以,注意当到达某一行或某一列的尽头时只能向下或向右走。从右下角向左上角走每个数都是一个阶段,当走到最左上角的数时即为从左上到右下的最小路径和。