【leetCode-DP】64. 最小路径和

给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。

说明:每次只能向下或者向右移动一步。

示例:

输入:
[
  [1,3,1],
  [1,5,1],
  [4,2,1]
]
输出: 7
解释: 因为路径 1→3→1→1→1 的总和最小。

结合我们的做题步骤:

1).定义一个能够清楚描述最优子问题的数组(明确数组描述的含义)。

2).找出数组元素之间的关系式(状态转移方程)

3).找出初始值

按照步骤完成解题:

1.定义dp[i][j] 代表 从(0,0)到当前位置(i,j)路径和最小

2.我们知道dp[i][j]由 dp[i-1][j]或者dp[i][j-1]转移过来 由此我们可以得到状态转移方程: dp[i][j] = min(dp[i][j-1] , dp[i-1][j]) + grid[i][j];

3.初始化 

for(int i = 1;i < row;i++)
        dp[i][0] =dp[i-1][0] + grid[i][0];

for(int i = 1;i < col;i++)
        dp[0][i] =dp[0][i-1] + grid[0][i];

 

优化

同我们之前做的DP一样,在求解的时候发现并不需要保存整个矩阵的状态,只需要当前行和当前列即可,同时又可以进一步优化,既dp[j]代表 从(0,0)走到第i行 j列位置上,最小的路径元素和。不用保存整个矩阵的状态,一维dp数组 迭代表示不同行上的路径累积和状态 ,于是状态转移方程编程:

dp[j] = Math.min(dp[j],dp[j-1]) + grid[i][j];  其中Math.min()中的dp[j]标识i-1层的路径和状态 ,等号左边的dp[j]标识i行的状态

        dp[0] = grid[0][0];
        //初始化第0行的dp状态
        for(int j = 1; j < col; j++){
            dp[j] = dp[j-1] + grid[0][j];
        }

        for(int i = 1; i < row; i++){
            //初始化第i行 0列的dp状态
            dp[0] += grid[i][0] ;
            for(int j = 1; j < col; j++){
                dp[j] = Math.min(dp[j],dp[j-1]) + grid[i][j];
            }
        }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章