zoukankan      html  css  js  c++  java
  • leetcode 174. Dungeon Game (地下城游戏)

    The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. The dungeon consists of M x N rooms laid out in a 2D grid. Our valiant knight (K) was initially positioned in the top-left room and must fight his way through the dungeon to rescue the princess.

    The knight has an initial health point represented by a positive integer. If at any point his health point drops to 0 or below, he dies immediately.

    Some of the rooms are guarded by demons, so the knight loses health (negative integers) upon entering these rooms; other rooms are either empty (0's) or contain magic orbs that increase the knight's health (positive integers).

    In order to reach the princess as quickly as possible, the knight decides to move only rightward or downward in each step.

    Write a function to determine the knight's minimum initial health so that he is able to rescue the princess.

    For example, given the dungeon below, the initial health of the knight must be at least 7 if he follows the optimal path RIGHT-> RIGHT -> DOWN -> DOWN.

    -2 (K) -3 3
    -5 -10 1
    10 30 -5 (P)

    Note:

    • The knight's health has no upper bound.
    • Any room can contain threats or power-ups, even the first room the knight enters and the bottom-right room where the princess is imprisoned.

    题目大意:骑士从左上角的房间进入,想要救回位于右下角的公主,至少需要多少滴血。(在任意时刻,他的生命点数<= 0, 他会立刻死。),在每个房间他要么减血,要么回复。

    思路:动态规划

    我们定义dp[i][j]表示从位置(i, j)到从右下角成功活着出来至少需要多少滴血。假设右下角位置(m - 1, n - 1), 成功出来到达(m, n - 1) 或者 (m - 1, n)至少要有1滴血。dp[m][n - 1] = 1, dp[m - 1][n] = 1.

    如果dungeon[m - 1][n - 1] < 0, dp[m - 1][n - 1] = min(dp[m][n - 1], dp[m - 1][n]) - dungeon[m - 1][n - 1],

    否则 dp[m - 1][n - 1] = 1.

    状态转移方程:dp[i][j] = min(dp[i + 1][j], dp[i][j + 1]) - dungeon[i][j], if dungeon[i][j] <= 0

                                        = 1, else dungeon[i][j] > 0

     1 class Solution {
     2 public:
     3     int calculateMinimumHP(vector<vector<int>>& dungeon) {
     4         int m = dungeon.size();
     5         if (m == 0)
     6             return 1;
     7         int n = dungeon[0].size();
     8         vector<vector<int> > dp(m + 1, vector<int>(n + 1, INT_MAX));
     9         dp[m][n - 1] = 1;
    10         dp[m - 1][n] = 1;
    11         for (int i = m - 1; i >= 0; i--) {
    12             for (int j = n - 1; j >= 0; j--) {
    13                 int need = min(dp[i][j + 1], dp[i + 1][j]) - dungeon[i][j];
    14                 dp[i][j] = need > 0 ? need : 1;
    15             }
    16         }
    17         return dp[0][0];
    18     }
    19 };
  • 相关阅读:
    Fiddler 教程
    Android 利用 aapt 解析 apk 得到应用名称 包名 版本号 权限等信息
    Android获取Manifest中<meta-data>元素的值
    Android资源混淆保护实践
    Android中捕获TTextView文本中的链接点击事件方法
    Android APK 手动命令编译、打包、签名步骤
    Android签名总结
    软件概要设计模板
    整理了一份React-Native学习指南
    appium简明教程(转)
  • 原文地址:https://www.cnblogs.com/qinduanyinghua/p/11525644.html
Copyright © 2011-2022 走看看