有点类似矩阵的最小路径和,但是是从右下往上推的。
class Solution {
public:
int calculateMinimumHP(vector<vector<int>>& dungeon) {
//思路:需要计算最少所需的健康点,可以从最后的位置向前推
//因为最后位置所需的最少健康点是确定的
//由于骑士可以向右和向下,那么倒过来就是向左和向上推
//记dp[i][j]为i,j位置所需的最少血量,那么
//dp[i][j]=min{右边的最小,下边的最小}-dungeon[i][j] //dungeon[i][j]<min{右边的最小,下边的最小}
//dp[i][j]=1 //dungeon[i][j]>=min{右边的最小,下边的最小}
vector<vector<int> > dp(dungeon.size(),vector<int>(dungeon[0].size()));
int N=dungeon.size();
int M=dungeon[0].size();
dp[N-1][M-1]=dungeon[N-1][M-1]>=0?1:(1-dungeon[N-1][M-1]);
//初始化 最后一行和最后一列的最少血量需求
for (int i = N - 2; i >= 0; i--)
{
dp[i][M - 1] = dungeon[i][M - 1] >= dp[i+1][M - 1] ? 1 : (dp[i + 1][M - 1] - dungeon[i][M - 1]);
}
for (int j = M - 2; j >= 0; j--)
{
dp[N - 1][j] = dungeon[N - 1][j] >= dp[N - 1][j + 1] ? 1 : (dp[N - 1][j + 1] - dungeon[N - 1][j]);
}
for (int i = N - 2; i >= 0; i--)
for (int j = M - 2; j >= 0; j--)
{
int mini= min(dp[i + 1][j], dp[i][j + 1]);
dp[i][j] = max(mini-dungeon[i][j],1);
}
return dp[0][0];
}
};