Title

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

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

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

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

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

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

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

说明:

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

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

动态规划

考虑从右下往左上进行动态规划。令 dp[i][j] 表示从坐标 (i,j) 到终点所需的最小初始值。换句话说,当我们到达坐标 (i,j) 时,如果此时我们的路径和不小于 dp[i][j] ,我们就能到达终点。

这样一来,我们就无需担心路径和的问题,只需要关注最小初始值。对于 dp[i][j],我们只要关心 dp[i][j+1] 和 dp[i+1][j] 的最小值 minn。记当前格子的值为 dungeon(i,j),那么在坐标 (i,j) 的初始值只要达到 minn−dungeon(i,j) 即可。同时,初始值还必须大于等于 1。这样我们就可以得到状态转移方程:

dp[i][j]=max(min(dp[i+1][j],dp[i][j+1])−dungeon(i,j),1)dp[i][j]=max(min(dp[i+1][j],dp[i][j+1])−dungeon(i,j),1)dp[i][j]=max(min(dp[i+1][j],dp[i][j+1])−dungeon(i,j),1)
最终答案即为 dp[0][0]。

边界条件为,当 i=n-1 或者 j=m-1 时,dp[i][j] 转移需要用到的 dp[i][j+1] 和 dp[i+1][j] 中有无效值,因此代码实现中给无效值赋值为极大值。特别地,dp[n-1][m-1] 转移需要用到的 dp[n−1][m] 和 dp[n][m-1] 均为无效值,因此我们给这两个值赋值为 1。

Code

 def calculateMinimumHP(self, dungeon: List[List[int]]) -> int:rows, cols = len(dungeon), len(dungeon[0])dp = [[10 ** 9] * (cols + 1) for _ in range(rows + 1)]dp[rows][cols -1] = dp[rows - 1][cols] = 1for i in range(rows - 1, -1, -1):for j in range(cols - 1, -1, -1):minn = min(dp[i + 1][j], dp[i][j + 1])dp[i][j] = max(minn - dungeon[i][j], 1)return dp[0][0]

复杂度分析

时间复杂度:O(N×M),其中 N,M 为给定矩阵的长宽。

空间复杂度:O(N×M),其中 N,M 为给定矩阵的长宽,注意这里可以利用滚动数组进行优化,优化后空间复杂度可以达到 O(N)。

174. Dungeon Game 地下城游戏相关推荐

  1. Leetcode 174. Dungeon Game 地下城游戏

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

  2. [Leetcode][第174题][JAVA][地下城游戏][DFS][动态规划]

    [问题描述][中等] [解答思路] 1. 回溯(暴力)& 优化 超时,需要优化 public int calculateMinimumHP(int[][] dungeon) {if (dung ...

  3. 174. 地下城游戏(Dungeon Game)

    174. 地下城游戏(Dungeon Game) 题解 动态规划 复杂度分析 Python Java(待完成) 题解 动态规划 dp[i][j]dp[i][j]dp[i][j]表示到达房间dungeo ...

  4. 力扣174. 地下城游戏

    力扣174. 地下城游戏 文章目录 力扣174. 地下城游戏 一.题目描述 二.分析 三.完整代码 一.题目描述 二.分析 这个题一看就可以用动态规划,就需要确定动态规划的状态和选择以及状态转移方程 ...

  5. leetcode 思路——64. 最小路径和——174. 地下城游戏

    leetcode 思路--64. 最小路径和--174. 地下城游戏 64. 最小路径和 174. 地下城游戏 64. 最小路径和 给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角 ...

  6. [算法]LeetCode每日一题--174. 地下城游戏(Java)

    DailyChallenge 174. 地下城游戏 Hard20200712 Description 一些恶魔抓住了公主(P)并将她关在了地下城的右下角.地下城是由 M x N 个房间组成的二维网格. ...

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

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

  8. 力扣 -- 174. 地下城游戏

    题目链接:174. 地下城游戏 - 力扣(LeetCode) 下面是用动态规划的思想解决这道题的过程,相信各位小伙伴都能看懂并且掌握这道经典的动规题目滴. 参考代码: class Solution { ...

  9. 174.地下城游戏(难)

    目录 一.题目 二.分析+代码 方法一:先初始化最后一列和最后一行 方法二:多加一行和一列 一.题目 174. 地下城游戏 - 力扣(LeetCode) 二.分析+代码 方法一:先初始化最后一列和最后 ...

最新文章

  1. 极速理解设计模式系列:23.装饰器模式(Decorator Pattern)
  2. OpenCV学习之Scalar数据类型
  3. Swagger2介绍
  4. python pip修改安装镜像源
  5. centos minimal 安装无法自定义分区
  6. Python基础(七)--模块和包
  7. Spring Cloud与微服务学习总结(1)——Spring Cloud及微服务入门
  8. 知识整理2019清北学堂提高储备D1
  9. 大数取模运算Barrett reduction
  10. python 英语词频统计_Python实现统计英文文章词频的方法分析
  11. 这款网页翻译插件,用了就舍不得戒掉
  12. Linux-frp内网穿透
  13. 嵌入式工作会越来越少吗?
  14. Windows8.1设置默认输入法为英文
  15. 8255芯片实现7段LED显示器
  16. 7-99 含有2个运算符的算数表达式(选作)
  17. 数学和英语不好,能当程序员吗?
  18. 基于Vue和SpringBoot的便利店仓库物资管理系统的设计与实现
  19. 【JAVA学习笔记】
  20. php web开发的不足之一:无法常驻内存

热门文章

  1. 【腾讯Bugly干货分享】动态链接库加载原理及HotFix方案介绍
  2. php四种基础排序算法的运行时间比较
  3. cmd chcp命令切换字符格式UTF8
  4. mysql 5.0存储过程学习总结
  5. yii2 mysql_Yii2 数据库操作汇总
  6. 汉诺塔函数python_帮你轻松理解《汉诺塔》函数
  7. Linux nano编辑txt文件,Linux 文本编辑器 nano 的简单使用
  8. mysql数据库在什么上运行_mysql – 在所有数据库上运行SQL查询
  9. java编译时多态和运行时多态_运行时多态、编译时多态和重载、重写的关系(不区分Java和C#,保证能看懂!)...
  10. android各层之间,Android运行程序在各层架构之间的相互关系