问题描述

骑士要从房间左上角走到右下角,每次只能向右或向下走一步。 房间里的数字表示骑士生命值的变化值,骑士血量归零就会死亡,至少要有 1 点 HP。 骑士为了救到公主,至少需要多少点生命值? 走迷宫问题 - 图1 上图所需最少HP为7。

分析

这个题的关键在于:不仅要求路程和,还要确保路上的每个点HP都大于0。
他的小规模的问题是从右下角开始的,而不是左上角。具有最优子结构。

dp[i][j]表示从这个格子到达终点至少需要的血量,转移方程为:
走迷宫问题 - 图2

  1. int calculateMinimumHP(vector<vector<int>>& dungeon) {
  2. int m = dungeon.size();
  3. int n = dungeon[0].size();
  4. // 初始化最后一行
  5. dungeon[m - 1][n - 1] = max(1 - dungeon[m - 1][n - 1], 1);
  6. for (int j = n - 2; j >= 0; --j)
  7. dungeon[m - 1][j] = max(dungeon[m - 1][j + 1] - dungeon[m - 1][j], 1);
  8. // 初始化最后一列
  9. for (int i = m - 2; i >= 0; --i)
  10. dungeon[i][n - 1] = max(dungeon[i + 1][n - 1] - dungeon[i][n - 1], 1);
  11. // 其他行列
  12. for (int i = m - 2; i >= 0; --i)
  13. for (int j = n - 2; j >= 0; --j)
  14. dungeon[i][j] = min(
  15. max(dungeon[i + 1][j] - dungeon[i][j], 1),
  16. max(dungeon[i][j + 1] - dungeon[i][j], 1));
  17. return dungeon[0][0];
  18. }