一些恶魔抓住了公主(P)并将她关在了地下城的右下角。地下城是由 M x N 个房间组成的二维网格。我们英勇的骑士(K)最初被安置在左上角的房间里,他必须穿过地下城并通过对抗恶魔来拯救公主。

骑士的初始健康点数为一个正整数。如果他的健康点数在某一时刻降至 0 或以下,他会立即死亡。

有些房间由恶魔守卫,因此骑士在进入这些房间时会失去健康点数(若房间里的值为负整数,则表示骑士将损失健康点数);其他房间要么是空的(房间里的值为 0),要么包含增加骑士健康点数的魔法球(若房间里的值为正整数,则表示骑士将增加健康点数)。

为了尽快到达公主,骑士决定每次只向右或向下移动一步。

编写一个函数来计算确保骑士能够拯救到公主所需的最低初始健康点数。

例如,考虑到如下布局的地下城,如果骑士遵循最佳路径 右 -> 右 -> 下 -> 下,则骑士的初始健康点数至少为 7。

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

说明:

骑士的健康点数没有上限。

任何房间都可能对骑士的健康点数造成威胁,也可能增加骑士的健康点数,包括骑士进入的左上角房间以及公主被监禁的右下角房间。

这题想了两天,最后也没搞出来,看了大佬的思路,才会的。。。。

这道题意思就是从左上角如何到右下角,只能向右,向下,在这之间有加血,有扣血,如何初始血量使得正好到达。

其实我们可以倒过来想。从右下角保持多少血量能到达左上角。

我们用 dp[i][j]表示在i,j位置最少需要的血量

动态方程:dp[i][j] = max(1, min(dp[i+1][j], dp[i][j+1]) - dungeon[i][j])

最后一行和最后一列做特殊处理

题中给的案例是:

-2  -3     3

-5  -10   1

10  30   -5

那么从最后一点开始推测,最后一点需要6点血才可以

那么他上面那一行的1处因为可以加一点血,所以到那有五点血就可以

最后推导出来各点的血量就是:

7   5   2

6   11  5

1   1   6

提交的代码:

class Solution {
    public int calculateMinimumHP(int[][] dungeon) {
    int m = dungeon.length;
        int n = dungeon[0].length;
        int[][] dp = new int[m][n];
        int i,j;
        if(dungeon[m-1][n-1]<0)
        {
            dp[m-1][n-1]=1+java.lang.Math.abs(dungeon[m-1][n-1]);
        }
        else
        {
            dp[m-1][n-1]=1;
        }
        for(i=m-1;i>=0;i--)
        {
            for(j=n-1;j>=0;j--)
            {
                if(i==m-1&&j!=n-1)
                {
                    dp[i][j] = java.lang.Math.max(1,dp[i][j+1]-dungeon[i][j]);
                }
                else if(i!=m-1&&j==n-1)
                {
                    dp[i][j] = java.lang.Math.max(1,dp[i+1][j]-dungeon[i][j]);
                }
                else if(i!=m-1&&j!=n-1)
                {
                    dp[i][j] = java.lang.Math.max(1,java.lang.Math.min(dp[i+1][j],dp[i][j+1])-dungeon[i][j]);
                }
            }
            
        }
        return dp[0][0];
    }
}

完整的代码:

public class Solution174 {
    public static int calculateMinimumHP(int[][] dungeon) {
        int m = dungeon.length;
        int n = dungeon[0].length;
        int[][] dp = new int[m][n];
        int i,j;
        if(dungeon[m-1][n-1]<0)
        {
            dp[m-1][n-1]=1+java.lang.Math.abs(dungeon[m-1][n-1]);
        }
        else
        {
            dp[m-1][n-1]=1;
        }
        for(i=m-1;i>=0;i--)
        {
            for(j=n-1;j>=0;j--)
            {
                if(i==m-1&&j!=n-1)
                {
                    dp[i][j] = java.lang.Math.max(1,dp[i][j+1]-dungeon[i][j]);
                }
                else if(i!=m-1&&j==n-1)
                {
                    dp[i][j] = java.lang.Math.max(1,dp[i+1][j]-dungeon[i][j]);
                }
                else if(i!=m-1&&j!=n-1)
                {
                    dp[i][j] = java.lang.Math.max(1,java.lang.Math.min(dp[i+1][j],dp[i][j+1])-dungeon[i][j]);
                }
            }
            
        }
        return dp[0][0];
        
    }
    public static void main(String[] args)
    {
        int[][] nums = {{-2,-3,3},{-5,-10,1},{10,30,-5}};
        //int[][] nums = {{0,0,0},{1,1,-1}};
        //int[][] nums = {{-200}};
        System.out.println(calculateMinimumHP(nums));
    }
}

Leetcode--174. 地下城游戏相关推荐

  1. LeetCode 174.地下城游戏

    LeetCode 174.地下城游戏 一些恶魔抓住了公主(P)并将她关在了地下城的右下角.地下城是由 M x N 个房间组成的二维网格.我们英勇的骑士(K)最初被安置在左上角的房间里,他必须穿过地下城 ...

  2. LeetCode 174. 地下城游戏 | Python

    文章目录 174. 地下城游戏 题目 解题思路 代码实现 实现结果 欢迎关注 174. 地下城游戏 题目来源:力扣(LeetCode)https://leetcode-cn.com/problems/ ...

  3. Java实现 LeetCode 174 地下城游戏

    174. 地下城游戏 一些恶魔抓住了公主(P)并将她关在了地下城的右下角.地下城是由 M x N 个房间组成的二维网格.我们英勇的骑士(K)最初被安置在左上角的房间里,他必须穿过地下城并通过对抗恶魔来 ...

  4. LeetCode 174. 地下城游戏(DP)

    文章目录 1. 题目 2. 解题 1. 题目 一些坏人抓住了公主(P)并将她关在了地下城的右下角. 地下城是由 M x N 个房间组成的二维网格. 我们英勇的骑士(K)最初被安置在左上角的房间里, 他 ...

  5. 【Java】LeetCode 174. 地下城游戏 —— 困难

    一些恶魔抓住了公主(P)并将她关在了地下城的右下角.地下城是由 M x N 个房间组成的二维网格.我们英勇的骑士(K)最初被安置在左上角的房间里,他必须穿过地下城并通过对抗恶魔来拯救公主. 骑士的初始 ...

  6. [C++] LeetCode 174. 地下城游戏

    题目 一些恶魔抓住了公主(P)并将她关在了地下城的右下角.地下城是由 M x N 个房间组成的二维网格.我们英勇的骑士(K)最初被安置在左上角的房间里,他必须穿过地下城并通过对抗恶魔来拯救公主. 骑士 ...

  7. 每日题解:LeetCode 174. 地下城游戏

    题目地址 个人博客地址 题目描述 一些恶魔抓住了公主(P)并将她关在了地下城的右下角.地下城是由 M x N 个房间组成的二维网格.我们英勇的骑士(K)最初被安置在左上角的房间里,他必须穿过地下城并通 ...

  8. [leetcode]174. 地下城游戏

    写了半天从[0][0]开始的,代码有90多行,就过了一个样例..看了题解,原来只能倒着来..额额 1.题解里写得最简洁的: https://leetcode-cn.com/problems/dunge ...

  9. leetcode 174:地下城游戏

    [分析]这道题一看就是动态规划,最开始从左上角往右下走,每次判断右侧和下侧哪个数大就走哪个方向,但是这样想的话就会有一个问题,就是我们需要判断每次到达一个房间后,我们的血量不能是负数.而问题的关键是骑 ...

  10. LeetCode 174. 地下城游戏

    题目链接: 力扣https://leetcode-cn.com/problems/dungeon-game/ [分析]一看向下和向右走,第一反应肯定是dp了.但是如果从左上角开始dp的话,加血会影响我 ...

最新文章

  1. HTML特殊字符编码对照表
  2. mysql core 文件_MySQL未能加载文件或程序集“Ubiety.Dns.Core”或它的某一个依赖项 问题的解决...
  3. 【Linux】31. ffmpeg常用命令
  4. 扫地机器人滤网顺序_1分钟小课堂:扫地机器人滤网多久换一次?
  5. antd table排序 vue_antd of Vue 之table组件踩坑记
  6. 北京 | 轻舟智航 招聘 感知算法工程师
  7. Java:对象创建和初始化过程
  8. Python开发环境Anaconda3使用指南(入门篇)
  9. 苹果手机默认拍照比例_苹果手机拍照有什么技巧?这几个功能要知道,不然别说自己用苹果...
  10. jquery开发插件_如何开发jQuery插件
  11. Win10下Linux子系统使用串口(不是USB转串口)
  12. Linux内核模块静态加载的顺序
  13. delphi xe6 让 ListView 在 Android 可回弹[根据龟山阿卍原创修改为xe6版本]
  14. 2013职称计算机幻灯片题库,2013职称计算机考试题库宝典及答案解析(全).doc
  15. 屏蔽网站、网页和弹窗的方法
  16. SYNCookie原理
  17. map返回另一个对象
  18. 手机为什么显示服务器升级,支付宝提示的支付服务升级是什么意思?
  19. 软考系统设计架构师经验与教训分享
  20. 二进制安装k8s集群V1.23.0

热门文章

  1. LeetCode 824. 山羊拉丁文
  2. LeetCode 1380. 矩阵中的幸运数(set)
  3. LeetCode 665. 非递减数列(双指针)
  4. LeetCode 260. 只出现一次的数字 III(位运算)
  5. oracle批量联机,Oracle 12.2 使用联机重定义对表进行多处改变
  6. docker php nginx,使用docker快速搭建nginx+php环境
  7. 爬虫小案例:基于Bing关键词批量下载图片
  8. php linux 删除文件夹,linux下如何删除文件夹
  9. java继承序列化_java中序列化之子类继承父类序列化
  10. pandas object转float_25个Pandas实用技巧