zoukankan      html  css  js  c++  java
  • LeetCode 174. 地下城游戏 dp

    地址 https://leetcode-cn.com/problems/dungeon-game/

    一些恶魔抓住了公主(P)并将她关在了地下城的右下角。地下城是由 M x N 个房间组成的二维网格。我们英勇的骑士(K)最初被安置在左上角的房间里,
    他必须穿过地下城并通过对抗恶魔来拯救公主。 骑士的初始健康点数为一个正整数。如果他的健康点数在某一时刻降至
    0 或以下,他会立即死亡。 有些房间由恶魔守卫,因此骑士在进入这些房间时会失去健康点数(若房间里的值为负整数,则表示骑士将损失健康点数);其他房间要么是空的(房间里的值为 0),
    要么包含增加骑士健康点数的魔法球(若房间里的值为正整数,则表示骑士将增加健康点数)。 为了尽快到达公主,骑士决定每次只向右或向下移动一步。   编写一个函数来计算确保骑士能够拯救到公主所需的最低初始健康点数。 例如,考虑到如下布局的地下城,如果骑士遵循最佳路径 右
    -> 右 -> 下 -> 下,则骑士的初始健康点数至少为 7-2 (K) -3 3 -5 -10 1 10 30 -5 (P)   说明: 骑士的健康点数没有上限。 任何房间都可能对骑士的健康点数造成威胁,也可能增加骑士的健康点数,包括骑士进入的左上角房间以及公主被监禁的右下角房间。

    算法1
    dp 从达到最后公主的房间 倒退前面的格子的进入最小体力值
    如果最后公主的房间为正数或者0 那么只要体力值为1就可以进入
    如果最后公主的房间为负数 那么体力值需要比负数的绝对值再大1

    class Solution {
    public:
    
    
    int calculateMinimumHP(vector<vector<int>>& dungeon) {
        vector<vector<int>> dp = dungeon;
        int m = dungeon.size();
        int n = dungeon[0].size();
    
        if (dungeon[m - 1][n - 1] >= 0) dp[m - 1][n - 1] = 1;
        else dp[m - 1][n - 1] = 1 - dungeon[m - 1][n - 1];
    
        for (int i = n - 2; i >= 0; i--) {
            if (dungeon[m - 1][i] >= dp[m - 1][i + 1]) dp[m - 1][i] = 1;
            else dp[m - 1][i] = dp[m - 1][i + 1] - dungeon[m - 1][i];
        }
    
        for (int i = m - 2; i >= 0; i--) {
            if (dungeon[i][n - 1] >= dp[i + 1][n - 1]) dp[i][n - 1] = 1;
            else dp[i][n - 1] = dp[i + 1][n - 1] - dungeon[i][n - 1];
        }
    
        for (int i = m - 2; i >= 0; i--) {
            for (int j = n - 2; j >= 0; j--) {
                int dp1 = 0; int dp2 = 0;
    
                if (dungeon[i][j] >= dp[i + 1][j]) dp1 = 1;
                else dp1 = dp[i + 1][j] - dungeon[i][j];
    
                if (dungeon[i][j] >= dp[i][j + 1]) dp2 = 1;
                else dp2 = dp[i][j + 1] - dungeon[i][j];
    
                dp[i][j] = min(dp1, dp2);
    
            }
        }
    
    
        return dp[0][0];
    }
    
    
    
    };
    class Solution {
    public:
        vector<vector<int>> dp;
    
        int calculateMinimumHP(vector<vector<int>>& dungeon) {
            int m = dungeon.size();
            int n = dungeon[0].size();
    
            if (m == 1 && n == 1) {
                if (dungeon[0][0] >= 0) return 1;
                else return 1 - dungeon[0][0];
            }
    
    
            dp = vector<vector<int>>(m + 10, vector<int>(n + 10));
    
            dp[m - 1][n - 1] = 1 - dungeon[m - 1][n - 1];
            dp[m - 1][n - 1] = max(dp[m - 1][n - 1], 1);
        
            for (int x = m - 1; x >= 0; x--) {
                for (int y = n - 1; y >= 0; y--) {
                    if (x == m - 1 && y == n - 1) continue;
                    int ans1 = 999999;
                    int ans2 = 999999;
                    if (x + 1 < m) {
                        ans1 = dp[x + 1][y] - dungeon[x][y];
                        ans1 = max(ans1, 1);
                    }
    
                    if (y + 1 < n) {
                        ans2 = dp[x][y+1] - dungeon[x][y];
                        ans2 = max(1, ans2);
                    }
                    dp[x][y] = min(ans1,ans2);
                }
            }
    
            return dp[0][0];
        }
    };
    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    selenium webdriver 执行Javascript
    selenium webdriver 定位元素 第一部分
    selenium webdriver 模拟鼠标悬浮
    JaveWeb 公司项目(3)----- 通过Thrift端口获取数据库数据
    JaveWeb 公司项目(2)----- 类模态窗口显示DIV并将DIV放置在屏幕正中间
    JaveWeb 公司项目(1)----- 使Div覆盖另一个Div完成切换效果
    Intellij Idea修改css文件即时更新生成效果
    Intellij idea 2017 图标含义
    下载安装tomcat和jdk,配置运行环境,与Intellij idea 2017关联
    IntelliJ IDEA Tomcat中端口被占用的问题
  • 原文地址:https://www.cnblogs.com/itdef/p/13288995.html
Copyright © 2011-2022 走看看