题干: 给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。
示例: 输入: [ [1,3,1], [1,5,1], [4,2,1] ] 输出: 7 解释: 因为路径 1→3→1→1→1 的总和最小。解题思路: | 1 | 2 | | 3 | 4 | 以该矩阵为例,若想知道该矩阵到4的最小路径,其实只需要对比2,3哪个更小即可,选择小的那边,因此可以使用动态规划。 动态规划的三步: 1.状态定义: 假设dp[ i ][ j ]表示到达矩阵(i, j)处,最短路径的值。 2.状态转移方程: 对于(i, j)他的路径只能从(i - 1, j)和(i, j - 1)两个地方到来。因此,状态转移方程为: dp[ i ][ j ] = max(dp[ i - 1 ][ j ], dp[ i ][ j - 1]) + grid[ i ][ j ] 3.边界条件: i == 0 && j == 0时,dp[ 0 ][ 0 ] = grid[ 0 ][ 0 ]; i == 0 && j > 0时,dp[ i ][ j ] = dp[ 0 ][ j - 1] + grid[ i ][ j ] ; i > 0 && j == 0时,dp[ i ][ j ] = dp[ i - 1 ][ 0 ] + grid[ i ][ j ];
代码实现:
int minPathSum(int** grid, int gridSize, int* gridColSize) { int i, j; int** dp = (int**)malloc(sizeof(int*) * gridSize); for (int a = 0; a < gridSize; a++) { dp[a] = (int*)malloc(sizeof(int) * gridColSize[a]); } dp[0][0] = grid[0][0]; for (i = 1; i < gridSize; i++) { dp[i][0] = dp[i - 1][0] + grid[i][0]; } for (j = 1; j < (* gridColSize); j++) { dp[0][j] = dp[0][j - 1] + grid[0][j]; } for (i = 1; i < gridSize; i++) { for (j = 1; j < (* gridColSize); j++) { dp[i][j] = (dp[i - 1][j] < dp[i][j - 1] ? dp[i - 1][j] : dp[i][j - 1]) + grid[i][j]; } } return dp[i - 1][j - 1]; }