被面试官问到的数据结构与算法--动态规划解礼物的最大价值

题目

在 一 个 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];
    }

 其他说明

动态规划是求解决策过程最优化的数学方法。如果一个问题可以分解成若干个子问题,并且子问题之间还有重叠的更小的子问题,就可以考虑用动态规划来解决这个问题。应用动态规划之前要分析能否把大问题分解成小问题,分解后的每个小问题也存在最优解。如果将小问题的最优解组合起来能够得到整个问题的最优解,那么就可以使用动态规划解决问题。

可以应用动态规划求解的问题主要由四个特点:

  1. 问题是求最优解
  2. 整体问题的最优解依赖于各个子问题的最优解
  3. 大问题分解成若干小问题,这些小问题之间还有相互重叠的更小的子问题
  4. 从上往下分析问题,从下往上求解问题

可以使用动态规划的问题一般都有一些特点可以遵循。如题目的问法一般是三种方式:

  1. 求最大值/最小值
  2. 求可不可行
  3. 求方案总数

以上。

posted @ 2021-08-16 15:09  未知的九月  阅读(90)  评论(0编辑  收藏  举报