最小路径和(动态规划问题)详解+代码

给定一个,包含非负整数的 m x n 网格。请找出一条,从左上角到右下角的路径。使得路径上,所有数字总和为最小,每次只能向下,或者向右移动一步。例如:

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

详解

 

首先,我们看约束条件!!
从左上角出发,到右下角去,只允许向下或者向右移动。
寻找此时的最小路径,我们可以将其分解为,到达每一个元素所要的最小路径,对于最后一个元素,只需要找他上一步的最小路径即可。(由于每个元素的最小路径斗鱼他上边或者左边的元素的最小路径有关,也即互相不独立的子问题。因此可以使用动态规划解决)
此时,我们可以想到,
对于第一行的所有元素,都可以从左上角的元素通过仅向右移动到达。
对于第一列的所有元素,都可以从左上角的元素通过仅向下移动到达。

创建二维数组dp[][],用来存储每个对应元素的最小路径。其大小与存储元素的数组grid[][]一样。

有如下公式:                      

第一个元素                           dp[0][0] = grid[0][0]

第一行,当 i = 0 且 j >  0, dp[0][j] = dp[0][j - 1] + grid[0][j]

第一列,当 i > 0 且 j = 0,  dp[i][0] = dp[i - 1][0] + grid[i][0]

其他,   当 i > 0 且 j > 0,  dp[i][j] = grid[i][j] + min(dp[i - 1][j],dp[i][j - 1])

def minPathSum(grid):
    if not grid or not grid[0]:
        return 0

    rows, columns = len(grid), len(grid[0])
    dp = [[0] * columns for _ in range(rows)]
    dp[0][0] = grid[0][0]
    for i in range(1, rows):
        dp[i][0] = dp[i - 1][0] + grid[i][0]
    for j in range(1, columns):
        dp[0][j] = dp[0][j - 1] + grid[0][j]
    for i in range(1, rows):
        for j in range(1, columns):
            dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j]

    return dp[rows - 1][columns - 1]


line = [[1,3 ,1],[1,5,1],[4,2,1]]
s = minPathSum(line)
print('最小路径和为:',s)

 

你可能感兴趣的:(动态规划,算法)