1. 题目描述
难度:困难
2. 题目分析
这道题是64.最小路径和的进阶版。但是这一题我们不能从左上向右下的顺序,而是**要从最后一步开始,从右下到左上的顺序。**我们知道骑士最少的健康点数为1,所以最后一步的点数为1,然后根据每个网格中的数据依次计算,到某个网格时的所剩余的最低健康点数。动态方程为:
对于M x N的网格:
如果得到的值小于等于0, 就将1存储在dp[i][j]中,因为骑士的健康点数是正整数。
3. C语言实现
代码如下:
// 返回最小值
int Min(int a, int b){
return a<b?a:b;
}
// 返回最小的健康点数
int GetMinHealthy(int harm){
return harm<=0?1:harm;
}
int calculateMinimumHP(int** dungeon, int dungeonSize, int* dungeonColSize){
int m = dungeonSize;
int n = dungeonColSize[0];;
int res;
// 动态申请数组
int** dp = (int **)malloc(sizeof(int *)*(m*n));
for(int i = 0; i < m; i++) dp[i] = (int *)malloc(sizeof(int)*n);
// 初始化dp数组
dp[m-1][n-1] = dungeon[m-1][n-1]<0?(1-dungeon[m-1][n-1]):1;
// 初始化最右边dp数组
for(int i = m-2; i >= 0; i--){
dp[i][n-1] = GetMinHealthy(dp[i+1][n-1] - dungeon[i][n-1]);
}
// 初始化最下边dp数组
for(int i = n-2; i >= 0; i--){
dp[m-1][i] = GetMinHealthy(dp[m-1][i+1] - dungeon[m-1][i]);
}
// 开始遍历
for(int i = m-2; i >= 0; i--){
for(int j = n-2; j >= 0; j--){
dp[i][j] = GetMinHealthy(Min(dp[i+1][j], dp[i][j+1]) - dungeon[i][j]);
}
}
return dp[0][0];
}
运行结果为: