被面试官问到的数据结构与算法--动态规划解礼物的最大价值
题目
在 一 个 m*n 的 棋 盘 的 每 一 格 都 放 有 一 个 礼 物 , 每 个 礼 物 都 有 一 定 的 价 值 ( 价 值 大 于
0 )。你可以从棋盘的左上角开 始 拿 格 子 里 的 礼 物 , 并 每 次 向 右 或 者 向 下 移 动 一 格 、 直 到
到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值
的礼物?
示例 1:
输入:
[
[ 1 , 3 , 1 ] ,
[ 1 , 5 , 1 ] ,
[ 4 , 2 , 1 ]
] 输
出: 1 2
解释: 路径 1 → 3 → 5 → 2 → 1 可以拿到最多价值的礼物
解决
public int maxValue(int[][] grid) { // 动态优化 // dp[i][j] = max(dp[i-1][j], dp[i][j-1]) + grid[i][j] if (null == grid || grid.length == 0) { return 0; } int row = grid.length; int column = grid[0].length; int[][] dp = new int[row][column]; dp[0][0] = grid[0][0]; // 最左一列 for (int i = 1; i < row; i++) { dp[i][0] = dp[i - 1][0] + grid[i][0]; } // 上面一行 for (int i = 0; i < column; i++) { dp[0][i] = dp[0][i - 1] + grid[0][i]; } for (int i = 1; i < row; i++) { for (int j = 1; j < column; j++) { dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]) + grid[i][j]; } } return dp[row - 1][column - 1]; }
其他说明
动态规划是求解决策过程最优化的数学方法。如果一个问题可以分解成若干个子问题,并且子问题之间还有重叠的更小的子问题,就可以考虑用动态规划来解决这个问题。应用动态规划之前要分析能否把大问题分解成小问题,分解后的每个小问题也存在最优解。如果将小问题的最优解组合起来能够得到整个问题的最优解,那么就可以使用动态规划解决问题。
可以应用动态规划求解的问题主要由四个特点:
- 问题是求最优解
- 整体问题的最优解依赖于各个子问题的最优解
- 大问题分解成若干小问题,这些小问题之间还有相互重叠的更小的子问题
- 从上往下分析问题,从下往上求解问题
可以使用动态规划的问题一般都有一些特点可以遵循。如题目的问法一般是三种方式:
- 求最大值/最小值
- 求可不可行
- 求方案总数
以上。