力扣 地下城游戏
https://leetcode-cn.com/problems/dungeon-game/comments/
求从左上角到右下角至少需要的体力值,网格中加号减号,就是健康值。中通不允许为0 或者更小
-2 -3 3
-5 -10 1
10 30 -5
到终点至少要有1个体力值,我们可以反向dp推导。
if(终点) {
//表示到终点那步至少需要保留的体力值
dp[i][j] = max(1, 1-data[i][j])
}
if(最后一行) {
当前格子只能从本行的后一个格子过来,所以
就是后一个格子至少的体力值减当前格子消耗的体力值
就是当前格子至少保留的体力值。
dp[i][j] = max(1, dp[i][j+1]-data[i][j])
}
if(最后一列) {
当前格子只能从本列的下一个格子过来,所以
就是下一个格子至少的体力值减当前格子消耗的体力值
就是当前格子至少保留的体力值。
dp[i][j] = max(1, dp[i+1][j]-data[i][j])
}
其他情况:
// 当前格子可以从下一个格子过来,或者从后一个格子过来
我们要取使用最小的体力值,和1比较要去最大的体力值。
因为如果dp[i][j] 值为负的,说明在移动的过程中,当前获取的体力值,
足以将后面的步子走完,所以在这一步只需要保留活着就好。
也就是每次和1比较
package com.company; public class DungeonGame { public static int calculateMinimumHP(int[][] dungeon) { int row = dungeon.length; int col = dungeon[0].length; int[][] dp = new int[row][col]; for(int i = row - 1; i >= 0; i--) { for (int j = col - 1; j >= 0; j--) { if(i==row-1&&j==col-1) { dp[i][j] = Math.max(1, 1-dungeon[i][j]); } else if (i == row - 1) { dp[i][j] = Math.max(1,dp[i][j+1]-dungeon[i][j]); } else if (j == col - 1) { dp[i][j] = Math.max(1, dp[i+1][j]-dungeon[i][j]); } else { dp[i][j] = Math.max(1, Math.min(dp[i+1][j], dp[i][j+1])-dungeon[i][j]); } } } return dp[0][0]; } public static void main(String[] args) { int[][] dungeon = { {-2, -3, 3}, {-5, -10, 1}, {10, 30, -5} }; System.out.println(calculateMinimumHP(dungeon)); } }

浙公网安备 33010602011771号