原始题目:剑指 Offer 47. 礼物的最大价值 (opens new window)
解题思路:
可以使用动态规划来解决。
题目说从左上角开始拿礼物,每次只能向下或者向右移动一格,一直拿到右下角,要求到右下角时拿到的礼物的价值最大。
设 表示从左上角经过向下或者向右走到单元格 的礼物最大价值。 的价值是
显然, 的价值是由上一个单元格( 或者 的较大者)的最大价值加上当前单元格 的价值决定的。可以得到以下的递推关系:
动态规划解析
状态定义:设动态规划矩阵 , 表示由棋盘的左上角开始,到达单元格 的最大价值。
**初始状态:**为了代码的简洁性, 和 统一规定为 ,方便后面计算。否则需要考虑边界条件,多加几个判断。
转移方程: 和 均从 开始算起
**返回值:**返回 , 和 分别为矩阵的行高和列宽,即返回 矩阵的右下角元素。
当然也可以直接将原二维数组作为 矩阵来算,只是这样会改变数组原先的数据。
代码:
public int maxValue(int[][] grid) {
int row = grid.length;
int col = grid[0].length;
int[][] dp = new int[row + 1][col + 1];
for (int x = 1; x <= row; x++) {
for (int y = 1; y <= col; y++) {
dp[x][y] = Math.max(dp[x - 1][y], dp[x][y - 1]) + grid[x - 1][y - 1];
}
}
return dp[row][col];
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
复杂度分析
- 时间复杂度:, 分别为矩阵行高、列宽;动态规划需要遍历整个 矩阵,使用 时间。
- 空间复杂度: 矩阵需要 的额外空间。