• [LeetCode] Dungeon Game


    (Version 0.0)

    应该说这是一道入门级的典型DP题目,因为可以较为明显地看出进入当前考虑的格子需要的HP值依赖于在进入这个格子之后往哪个方向走,也就是说依赖于进入当前格子的下方格子和右边格子所需要的HP值的最小可能值。这样一来我们可以把子问题抽象成:如果整个dungeon的左上角是当前在考虑的格子,最终目标是救出最右下角的公主,求所需要的初始HP值的可能最小值。

    在代码实现中,如果用一个二维数组中的元素require[i][j]来维护进入dungeon[i][j]所需的最小HP值,则状态转移关系为:require[i][j] = dungeon[i][j] >= minRequire ? 1 : minRequire - dungeon[i][j],其中minRequire是进入dungeon[i + 1][j]和dungeon[i][j + 1]所需的HP值中较小的那个。也就是说,如果dungeon[i][j]可以满足进入下一个格子(右边的或者下边的格子),那么进入dungeon[i][j]的条件仅仅是你还活着,即HP值为1(其实有一种情况下即使dungeon[i][j]比进入下一格子需要的最小值还小也可以,即dungeon[i][j] = minRequire - 1,因为你进入dungeon[i][j]时是自带1点的HP的,所以少1也可以,不过这种情况其实与后面要说的情况在代码求解上是一样的,所以为了代码简短,在实现上就归类到后面一种去了);如果dungeon[i][j]不能满足进入下一个格子,那么进入dungeon[i][j]的条件就是你在进入dungeon[i][j]前的HP值必须至少也能解决掉经过dungeon[i][j]补给之后继续往后走的HP需求,即minRequire - dungeon[i][j]。代码如下:

     1 public class Solution {
     2     public int calculateMinimumHP(int[][] dungeon) {
     3         int[][] require = new int[dungeon.length][dungeon[0].length];
     4         int buttom = dungeon.length - 1;
     5         int right = dungeon[0].length - 1;
     6         require[buttom][right] = dungeon[buttom][right] >= 0 ? 1 : 1 - dungeon[buttom][right];
     7         for (int i = dungeon[0].length - 2; i >= 0; i--) {
     8             require[buttom][i] = dungeon[buttom][i] >= require[buttom][i + 1] ? 1 : require[buttom][i + 1] - dungeon[buttom][i];
     9         }
    10         for (int i = dungeon.length - 2; i >= 0; i--) {
    11             require[i][right] = dungeon[i][right] >= require[i + 1][right] ? 1 : require[i + 1][right] - dungeon[i][right];
    12         }
    13         for (int i = dungeon.length - 2; i >= 0; i--) {
    14             for (int j = dungeon[0].length - 2; j >= 0; j--) {
    15                 int minRequire = Math.min(require[i + 1][j], require[i][j + 1]);
    16                 require[i][j] = dungeon[i][j] >= minRequire ? 1 : minRequire - dungeon[i][j];
    17             }
    18         }
    19         return require[0][0];
    20     }
    21 }

    总体而言,这是一道比较中规中矩的动态规划题目,其中子问题的定义比较直接,optimal substructure也比较明显地可以看到,个人感觉比较适合动态规划入门水平的练习。

  • 相关阅读:
    oracle 中增加、修改、删除字段
    Oracle 中int , number的区别
    [转]信息系统项目管理师考试论文写作技巧
    项目论证
    java中异步计算之Future
    vmstat例子
    页面重构工作者的必备素质,转载
    办公室人员对号入座太经典啦!
    大家多注意身体!
    经典!牛人汽车防盗秘笈
  • 原文地址:https://www.cnblogs.com/icecreamdeqinw/p/4346812.html
Copyright © 2020-2023  润新知