Skip to content

Commit ba66009

Browse files
author
applewjg
committed
Add Solution Comment
Change-Id: I8a67293653e083d08a30f459371b1c6c1b72a28e
1 parent 6953277 commit ba66009

File tree

1 file changed

+19
-1
lines changed

1 file changed

+19
-1
lines changed

DungeonGame.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,25 @@ The demons had captured the princess (P) and imprisoned her in the bottom-right
2727
The knight's health has no upper bound.
2828
Any room can contain threats or power-ups, even the first room the knight enters and the bottom-right room where the princess is imprisoned.
2929
30-
Solution: ...
30+
Solution:
31+
Fortunately, this problem can be solved through a table-filling Dynamic Programming technique, similar to other "grid walking" problems:
32+
33+
To begin with, we should maintain a 2D array D of the same size as the dungeon, where D[i][j] represents the minimum health that guarantees the survival of the knight for the rest of his quest BEFORE entering room(i, j). Obviously D[0][0] is the final answer we are after. Hence, for this problem, we need to fill the table from the bottom right corner to left top.
34+
35+
Then, let us decide what the health should be at least when leaving room (i, j). There are only two paths to choose from at this point: (i+1, j) and (i, j+1). Of course we will choose the room that has the smaller D value, or in other words, the knight can finish the rest of his journey with a smaller initial health. Therefore we have:
36+
37+
min_HP_on_exit = min(D[i+1][j], D[i][j+1])
38+
Now D[i][j] can be computed from dungeon[i][j] and min_HP_on_exit based on one of the following situations:
39+
40+
If dungeon[i][j] == 0, then nothing happens in this room; the knight can leave the room with the same health he enters the room with, i.e. D[i][j] = min_HP_on_exit.
41+
If dungeon[i][j] < 0, then the knight must have a health greater than min_HP_on_exit before entering (i, j) in order to compensate for the health lost in this room. The minimum amount of compensation is "-dungeon[i][j]", so we have D[i][j] = min_HP_on_exit - dungeon[i][j].
42+
If dungeon[i][j] > 0, then the knight could enter (i, j) with a health as little as min_HP_on_exit - dungeon[i][j], since he could gain "dungeon[i][j]" health in this room. However, the value of min_HP_on_exit - dungeon[i][j] might drop to 0 or below in this situation. When this happens, we must clip the value to 1 in order to make sure D[i][j] stays positive: D[i][j] = max(min_HP_on_exit - dungeon[i][j], 1).
43+
Notice that the equation for dungeon[i][j] > 0 actually covers the other two situations. We can thus describe all three situations with one common equation, i.e.:
44+
45+
D[i][j] = max(min_HP_on_exit - dungeon[i][j], 1)
46+
for any value of dungeon[i][j].
47+
48+
Take D[0][0] and we are good to go. Also, like many other "table-filling" problems, the 2D array D can be replaced with a 1D "rolling" array here.
3149
*/
3250

3351
public class Solution {

0 commit comments

Comments
 (0)