问题描述
骑士要从房间左上角走到右下角,每次只能向右或向下走一步。 房间里的数字表示骑士生命值的变化值,骑士血量归零就会死亡,至少要有 1 点 HP。 骑士为了救到公主,至少需要多少点生命值?
上图所需最少HP为7。
分析
这个题的关键在于:不仅要求路程和,还要确保路上的每个点HP都大于0。
他的小规模的问题是从右下角开始的,而不是左上角。具有最优子结构。
dp[i][j]表示从这个格子到达终点至少需要的血量,转移方程为:
int calculateMinimumHP(vector<vector<int>>& dungeon) {int m = dungeon.size();int n = dungeon[0].size();// 初始化最后一行dungeon[m - 1][n - 1] = max(1 - dungeon[m - 1][n - 1], 1);for (int j = n - 2; j >= 0; --j)dungeon[m - 1][j] = max(dungeon[m - 1][j + 1] - dungeon[m - 1][j], 1);// 初始化最后一列for (int i = m - 2; i >= 0; --i)dungeon[i][n - 1] = max(dungeon[i + 1][n - 1] - dungeon[i][n - 1], 1);// 其他行列for (int i = m - 2; i >= 0; --i)for (int j = n - 2; j >= 0; --j)dungeon[i][j] = min(max(dungeon[i + 1][j] - dungeon[i][j], 1),max(dungeon[i][j + 1] - dungeon[i][j], 1));return dungeon[0][0];}
上图所需最少HP为7。