题目描述
- 给定一个二维数组 map ,含义是一张地图,例如,如下矩阵:
- —2, —3, 3
- —5, —10, 10
- 3, 0, —5
- 游戏的规则如下:
- 骑士从左上角出发、每次只能向右或向下走,最后到达右下角见到公主。
- 地图中每个位置的值代表骑士要遭遇的事情
- 如果是负数,说明此处有怪兽,要让骑士损失血量。
- 如果是非负数,代表此处有血瓶,能让骑士回血。
- 骑士从左上角到右下角的过程中,走到任何一个位置时,血量都不能少于1。
- 为了保证骑士能见到公主,初始血量至少是多少?
- 根据 map ,返回至少的初始血量。
code
public class Code44 {
public static int minHP(int[][] matrix) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return 0
}
int N = matrix.length
int M = matrix[0].length
return process(matrix, N, M, 0, 0)
}
// 来到了matrix[row][col],还没登上去,到达右下角,返回至少的初始血量
private static int process(int[][] matrix, int N, int M, int row, int col) {
// 即将来到右下角 需要的最少血量
if (row == N - 1 && col == M - 1) {
if (matrix[row][col] >= 0) {
// 只要有1点血量迈上去即可
return 1
} else {
// 负数 -3 -> 4 -(-3) + 1o
return -matrix[row][col] + 1
}
}
// 只能往右走
if (row + 1 == N) {
int right = process(matrix, N, M, row, col + 1)
// 如果当前位置的血量 大于等于 往右的所需要最少血量 直接返回1 踏上当前位置即可
int cur = matrix[row][col]
if (cur >= right) {
return 1
} else {
// 先登上 当前位置 + 往右的所需要最少血量
return -cur + right
}
}
// 只能往下走
if (col + 1 == M) {
int down = process(matrix, N, M, row + 1, col)
// 如果当前位置的血量 大于等于 往右的所需要最少血量 直接返回1 踏上当前位置即可
int cur = matrix[row][col]
if (cur >= down) {
return 1
} else {
// 先登上 当前位置 + 往下的所需要最少血量
return -cur + down
}
}
// 都可以走
int nextNeed = Math.min(process(matrix, N, M, row + 1, col), process(matrix, N, M, row, col + 1))
int cur = matrix[row][col]
if (cur >= nextNeed) {
return 1
} else {
// 先登上 当前位置 + 往右(下)的所需要最少血量
return -cur + nextNeed
}
}
// 每个位置只依赖他 右边的 下面的 右下角的位置
public static int minHP1(int[][] m) {
if (m == null || m.length == 0 || m[0] == null || m[0].length == 0) {
return 1
}
int row = m.length
int col = m[0].length
int[][] dp = new int[row--][col--]
dp[row][col] = m[row][col] > 0 ? 1 : -m[row][col] + 1
for (int j = col - 1
dp[row][j] = Math.max(dp[row][j + 1] - m[row][j], 1)
}
int right = 0
int down = 0
for (int i = row - 1
dp[i][col] = Math.max(dp[i + 1][col] - m[i][col], 1)
for (int j = col - 1
right = Math.max(dp[i][j + 1] - m[i][j], 1)
down = Math.max(dp[i + 1][j] - m[i][j], 1)
dp[i][j] = Math.min(right, down)
}
}
return dp[0][0]
}
public static void main(String[] args) {
int[][] map = {
{-2, -3, 3},
{-5, -10, 1},
{10, 30, -5},
}
System.out.println(minHP(map))
System.out.println(minHP1(map))
}
}