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

我们假设考虑dp[2][0],从上面-2,-5过来,最少需要8滴血,那么dp[i][j]就填8吗,还是填1(毕竟这个房间可以加10滴血,只要来的时候不死就行了)?这里就是问题所在。对于某个状态(即某个确切的i,j坐标),它对于之后的路径是有影响的。因为除了考虑安全到达当前状态之外,还需要考虑从当前状态不死安全抵达公主。(即怎么到达当前状态会对之后的状态造成影响,这就不符合动态规划的无后效性了)
顺便粘贴一个知乎的回答:https://www.zhihu.com/question/43361359/answer/129799087
从不同的路径走到一个共同状态,而后续的状态变迁都是一样的,和之前采用何种路径到这个状态没有关系,即前面的各种决策结果由这个状态表示,在考虑后半段的决策方面没有任何区别
那么为什么逆序就可以?因为动态规划是要求无后效性,而不要求无前效性(虽然没有这个名词)。我们逆序的dp[i][j]表示从当前位置开始,安全抵达公主所需的最少健康值,不考虑怎么到达i,j,而是只关心从i,j开始如何抵达公主。可以看到,我们对于状态的定义不包含该状态之前的事件,也就不会有什么当前状态之前的事件对当前状态之后 造成影响!
这是我的想法,如果有懂这方面的大佬麻烦评论指点一哈
代码:
class Solution:
def calculateMinimumHP(self, dungeon ) -> int:
m,n=len(dungeon),
if not m:
return
n=len(dungeon[])
dp=[[ for i in range(n)] for j in range(m)] #m行n列
#dp[i][j]为从当前房间出发能不死抵达公主所需的最低健康点数
dp[-][-]=max(,-dungeon[-][-])
for i in range(m-,-,-):
for j in range(n-,-,-):
if i==m- and j==n-:
continue
x1,x2=float('inf'),float('inf')
if i+<m:
x1=max(,dp[i+][j]-dungeon[i][j])
if j+<n:
x2=max(,dp[i][j+]-dungeon[i][j])
dp[i][j]=min(x1,x2)
# for x in dp:
# print(x)
return dp[][]
把最后一行、最后一列单独判断一下,别人的代码:
class Solution:
def calculateMinimumHP(self, dungeon: List[List[int]]) -> int:
dp = [[ for i in range(len(dungeon[]))] for j in range(len(dungeon))]
m = len(dungeon)
n = len(dungeon[])
dp[-][-] = max(, - dungeon[-][-])
for i in range(m-,-,-):
dp[i][-] = max(,dp[i+][-]-dungeon[i][-])
for j in range(n-,-,-):
dp[-][j] = max(, dp[-][j+] - dungeon[-][j])
for i in range(m-,-,-):
for j in range(n-,-,-):
dp[i][j] = max(,min(dp[i+][j],dp[i][j+])-dungeon[i][j])
return dp[][]
174. 地下城游戏(逆向DP)的更多相关文章
- leetcode 174. 地下城游戏 解题报告
leetcode 174. 地下城游戏 一些恶魔抓住了公主(P)并将她关在了地下城的右下角.地下城是由 M x N 个房间组成的二维网格.我们英勇的骑士(K)最初被安置在左上角的房间里,他必须穿过地下 ...
- Java实现 LeetCode 174 地下城游戏
174. 地下城游戏 一些恶魔抓住了公主(P)并将她关在了地下城的右下角.地下城是由 M x N 个房间组成的二维网格.我们英勇的骑士(K)最初被安置在左上角的房间里,他必须穿过地下城并通过对抗恶魔来 ...
- Leetcode 174.地下城游戏
地下城游戏 一些恶魔抓住了公主(P)并将她关在了地下城的右下角.地下城是由 M x N 个房间组成的二维网格.我们英勇的骑士(K)最初被安置在左上角的房间里,他必须穿过地下城并通过对抗恶魔来拯救公主. ...
- P2016 战略游戏——树形DP大水题
P2016 战略游戏 树形DP 入门题吧(现在怎么是蓝色标签搞不懂): 注意是看见每一条边而不是每一个点(因为这里错了好几次): #include<cstdio> #include< ...
- [JLOI2013]卡牌游戏 概率DP
[JLOI2013]卡牌游戏 概率DP 题面 \(dfs\)复杂度爆炸,考虑DP.发现决策时,我们只用关心当前玩家是从庄家数第几个玩家与当前抽到的牌是啥.于是设计状态\(f[i][j]\)表示有\(i ...
- Lua游戏逆向及破解方法介绍
Lua游戏逆向及破解方法介绍 背景介绍 随着手游的发展,越来越多的Cocos-lua端游开发者转移到手游平台.Lua脚本编写逻辑的手游也是越来越多,如梦幻西游.刀塔传奇.开心消消乐.游龙英雄.奇迹 ...
- FPS游戏逆向-方框透视(三角函数)
本套课程主要学习FPS类游戏安全 由于FPS类游戏本身的特性问题,可能产生一些通用的游戏安全问题 在通过逆向与正向对FPS类游戏分析之后,找到其可能出现的不安全点 才能更好的保护游戏不被外部力量侵犯 ...
- 174 Dungeon Game 地下城游戏
一些恶魔抓住了公主(P)并将她关在了地下城的右下角.地下城是由 M x N 个房间组成的二维网格布局.我们英勇的骑士(K)最初被安置在左上角的房间里,并且必须通过地下城对抗来拯救公主.骑士具有以正整数 ...
- NOIP2003pj数字游戏[环形DP]
题目描述 丁丁最近沉迷于一个数字游戏之中.这个游戏看似简单,但丁丁在研究了许多天之后却发觉原来在简单的规则下想要赢得这个游戏并不那么容易.游戏是这样的,在你面前有一圈整数(一共n个),你要按顺序将其分 ...
随机推荐
- P1525 关押罪犯【二分+二分图】
输入输出样例 输入 #1 复制 4 6 1 4 2534 2 3 3512 1 2 28351 1 3 6618 2 4 1805 3 4 12884 思路 对于要求最大值最小的问题,不难想到二分. ...
- Linux分区类型EXT2、EXT3、EXT4详解
一.EXT2与EXT3 Linux之前缺省情况下使用的文件系统为Ext2,ext2文件系统的确高效稳定.但是,随着Linux系统在关键业务中的应用,Linux文件系统的弱点也渐渐显露出来了:其中系统缺 ...
- oracke数据库分区新增
1.发现一些过程执行报错,报错原因是'ora-14400插入的分区关键字未映射到任何分区',原来是2020年库表的时间子分区未扩展: 2.扩展子分区的语句是 ALTER TABLE 表名 MODIFY ...
- UVA1395 (最苗条的最小生成树)
链接 https://vjudge.net/problem/UVA-1395 代码 #include<bits/stdc++.h> using namespace std; #define ...
- 0011 基于DRF框架开发(04 普通序列化器)
普通序列化器和模型无关,只是对针对提交字段的定义. 本文定义三个序列化器: 教师序列化器,学生序列化器,教师学生序列化器.这三个序列化器都使用普通序列化器. 1 教师序列化器 在Application ...
- PAT (Basic Level) Practice (中文)1066 图像过滤 (15 分)
图像过滤是把图像中不重要的像素都染成背景色,使得重要部分被凸显出来.现给定一幅黑白图像,要求你将灰度值位于某指定区间内的所有像素颜色都用一种指定的颜色替换. 输入格式: 输入在第一行给出一幅图像的分辨 ...
- LayIM聊天框全屏根据浏览器高宽自适应
个人博客 地址:http://www.wenhaofan.com/article/20190410190628 问题 由于LayIM没有处理聊天框在全屏状态下根据浏览器缩放处理高宽,所以会导致在浏览器 ...
- WPF Dispatcher.BeginInvoke子线程更新UI
在开发WPF应用时出现:”调用线程无法访问此对象,因为另一个线程拥有该对象.“ 是因为UI线程是WPF应用的主线程,若尝试子线程更新UI线程应使用Dispatcher.BeginInvoke()或者I ...
- Python入门常识【入门必学】
直接上内容: print print 隔行 / 连续 / 间隔输出 print(a) == print(a,end='\n') print(a, end='') print(a, end ...
- vue常用插件之视频播放(rtmp m3u8)
vue-video-player(5.0.2) 最近我的项目做了一个监控视屏的显示,后台提供的视屏格式是rtmp 后来又改为m3u8,没成功,原因是占用内存过大,所以取消了这种方式 一.安装 npm ...