問題:
給定一個(gè)只含非負(fù)整數(shù)的m*n網(wǎng)格,找到一條從左上角到右下角的可以使數(shù)字和最小的路徑。
你在同一時(shí)間只能向下或者向右移動(dòng)一步
分析:
- F(n,m)表示棋盤大小為n*m時(shí)走法數(shù)量
- F(n,m) = F(n-1,m) + F(n,m-1)
- 棋盤退化成條狀時(shí)邊界處理(此時(shí)只有一個(gè)方向)
代碼:
直觀理解,開二維數(shù)組
int minPathSum(vector<vector<int> > &grid) {
// write your code here
int m = grid.size();
int n = grid[0].size();
vector<vector<int>> dp(m,vector<int>(n,0));
dp[0][0]=grid[0][0];
for(int i=1;i<m;++i){
dp[i][0] = dp[i-1][0]+grid[i][0];
}
for(int j=1;j<n;++j){
dp[0][j] = dp[0][j-1]+grid[0][j];
}
for(int i=1;i<m;++i){
for(int j=1;j<n;++j){
dp[i][j] = grid[i][j]+min(dp[i-1][j],dp[i][j-1]);
}
}
return dp[m-1][n-1];
}
省去一維(習(xí)慣上保留一行,嚴(yán)格來說應(yīng)該保留m,n中長(zhǎng)度較小的一個(gè))
int minPathSum(vector<vector<int> > &grid) {
// write your code here
int m = grid.size();
int n = grid[0].size();
vector<int> dp(n);
dp[0]=grid[0][0];
for(int j=1;j<n;++j){
dp[j] = dp[j-1]+grid[0][j];
}
for(int i=1;i<m;++i){
for(int j=0;j<n;++j){
if(j==0){
dp[j] = grid[i][j]+dp[j];
}
else{
dp[j] = grid[i][j]+min(dp[j],dp[j-1]);
}
}
}
return dp[n-1];
}