Dungeon Game

Minimum starting HP to reach the bottom-right alive — DP from bottom-right backwards.

Hard
Time O(m * n) Space O(n)
LeetCode
4 min read
dp grid

Problem#

Grid of damage/heal values. Knight starts top-left moving right/down; must reach bottom-right with HP ≥ 1 at all times. Return the minimum starting HP.

Examples#

  • [[-2,-3,3],[-5,-10,1],[10,30,-5]]7

Constraints#

  • 1 <= m, n <= 200.

Approach#

DP from bottom-right backwards. dp[r][c] = minimum HP needed entering (r, c). dp[m-1][n-1] = max(1, 1 - grid[m-1][n-1]). Transition: dp[r][c] = max(1, min(dp[r+1][c], dp[r][c+1]) - grid[r][c]).

Solution#

Dungeon Game
class Solution {
public:
int calculateMinimumHP(vector<vector<int>>& g) {
int m = g.size(), n = g[0].size();
vector<vector<int>> dp(m + 1, vector<int>(n + 1, INT_MAX));
dp[m][n - 1] = dp[m - 1][n] = 1;
for (int r = m - 1; r >= 0; --r) {
for (int c = n - 1; c >= 0; --c) {
int need = min(dp[r + 1][c], dp[r][c + 1]) - g[r][c];
dp[r][c] = max(1, need);
}
}
return dp[0][0];
}
};

Editorial#

Forward DP doesn’t work — the future grid determines the past requirement. Backward DP frames it as “how much HP do I need entering here to survive the rest?”. max(1, …) clamps to alive minimum.

Complexity#

  • Time: O(m * n).
  • Space: O(m * n).

Concept revision#

Search ESC

Keyboard shortcuts

Shortcuts are disabled while typing in inputs.