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. ViewPager+RadioGroup实现标题栏切换,Fragment切换
  2. OpenCV图像处理使用笔记(六)——图像滤波
  3. 操作系统习题4—进程死锁
  4. Maximum Subarray with Sum/ Multiply
  5. 阿里云IoT Studio升级版新增解决方案引擎,大幅提升方案交付效率
  6. CodeForces - 1118F1 Tree Cutting (Easy Version)(树形dp)
  7. Android 如何添加一种锁屏方式
  8. [2021-09-09 T3] 序列/luogu P3943 星空(异或差分+bfs最短路+状压dp)
  9. linux c绑定cpu_Linux内核路径优化之多核心平台TCP优化
  10. (22)FPGA面试题名词解释IRQ、BIOS、USB、VHDL、SDR
  11. Un 进行攻击计时效果
  12. 关于Encode in UTF-8 without BOM
  13. C语言库函数WindowsSDK...
  14. Oracle 11g 表空间管理
  15. vue实现画出页面二维码的3种办法
  16. 乡村少年宫计算机教师简介,乡村少年宫教师感言
  17. Lua实战之以非科学记数法输出小数
  18. SQL Extractor 数据库修复取证大师软件功能介绍
  19. python获取财务数据曝光_Python-股票-从网易财经获取主要财务指标数据
  20. 如何通过GB35114国密标准接入到LiveGBS GB28181/GB35114监控平台

热门文章

  1. hive 小文件数据合并
  2. 基于CefGlue的桌面应用开发
  3. cookie的设置和获取
  4. 【bzoj4385】[POI2015]Wilcze doły
  5. nullnullGet previous business day
  6. 第三道深搜-----------hdu1016
  7. 使用squid代理时出现“The requested URL could not be retrieved”
  8. Java创建cookie和删除cookie
  9. 基于八叉树快速分类的Shear-Warp交互式体绘制算法
  10. python shell下载很慢_Python踩坑之旅其一杀不死的Shell子进程