Dungeon Game 解题心得
题目来源: https://leetcode.com/problems/dungeon-game/description/
题目描述
给出一个2D的地图,地图最左上方的骑士要到达地图最右下方的位置,拯救公主。
规则1:地图中的每个格子有扣血和补血的能力
规则2:骑士在地图上行走只有向下走 DOWN 和向右 RIGHT 走。
规则3:为了成功拯救公主,骑士必须保证在去往右下方的过程中血量 HP 超过0,包括到达右下方的时候。
所以为了拯救公主,需要确定一个最小初始血量值
HP
使得骑士可以沿着某一条最优的路径成功抵达右下角,拯救公主
题目要求:求骑士要拯救公主的最小初始血量
如下面的地图
地图:
-2 (K) -3 3
-5 -10 1
10 30 -5 (P)
最优路径是:RIGHT-> RIGHT -> DOWN -> DOWN.
使得最小初始血量为:7
解题思路
- 曾经碰到过的坑
- 在确定状态转移方程时,状态转移方程的含义确定好后却得不到最优结果,对于某些特殊情况没有完全考虑到
- 最初的状态转移方程设定为
- H(x,y) :表示从(0,0)到(x,y)所需要的最低初始血量
- L(x,y) :表示以初始血量 H(x,y) 从(0,0)到(x,y)剩余的血量
- 转移方程:有些复杂这里就不写了(PS:果然复杂的状态转移式不够优雅,一般不是最优解)
正确思路
- 查看了正确思路的我觉得又受益颇多,又有些困惑
受益的是这种状态转移表达式的简洁和易于理解
- H(x,y) :从(x,y)走到(N, M)的所需最低初始血量
- (PS:和我的想法相反,但是为什么有效我是不明白的)
- 转移方程: H(x,y)=min{H(x+1,y)+dungeon(x,y),H(x,y+1)+dungeon(x,y)}
- if H(x,y)<0 then H(x,y)=1;
- 相当简洁,但是有需要提醒的就是:
初始化地图为INT_MAX
(N,M-1)和(N-1,M)的位置需要另外赋值为1
有了转移方程后就好办,剩下的就是代码实现了:
代码传送门:https://github.com/zhanzongyuan/leetcode/blob/master/174_Dungeon%20Game.cpp
DP问题状态转移方程设定经验总结
- 题目所求值一般就是转移状态的value
- 转移方程如果过于复杂,说明可能思路错误了
- 同一个状态的定义可以反过来定义试试