【leetcode】Dungeon Game

本文解析了LeetCode中的一款游戏地图问题,骑士需要通过一个充满威胁与机遇的地图来营救公主。文章详细介绍了如何使用动态规划的方法确定骑士的最小初始健康值,以确保能够成功到达目的地。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

from : https://leetcode.com/problems/dungeon-game/

Some of the rooms are guarded by demons, so the knight loses health (negative integers) upon entering these rooms; other rooms are either empty (0's) or contain magic orbs that increase the knight's health (positive integers).

In order to reach the princess as quickly as possible, the knight decides to move only rightward or downward in each step.


Write a function to determine the knight's minimum initial health so that he is able to rescue the princess.

For example, given the dungeon below, the initial health of the knight must be at least 7 if he follows the optimal path RIGHT-> RIGHT -> DOWN -> DOWN.

-2 (K) -3 3
-5 -10 1
10 30 -5 (P)

Notes:

  • The knight's health has no upper bound.
  • Any room can contain threats or power-ups, even the first room the knight enters and the bottom-right room where the princess is imprisoned.

从右下角像左上角处理,dp[i][j]表示从坐标(i, j)到右下角所需的血量。初始化时假设最后剩余血里为0,而

状态转移方程:

dungeon[i][j] = max(min(dungeon[i][j+1], dungeon[i+1][j])-dungeon[i][j], 0)

public class Solution {
    public int calculateMinimumHP(int[][] dungeon) {
		int m = dungeon.length;
		int n = dungeon[0].length;
		dungeon[m - 1][n - 1] = max(0 - dungeon[m - 1][n - 1], 0);
		for (int i = m - 2; i >= 0; --i) {
			dungeon[i][n - 1] = max(dungeon[i + 1][n - 1] - dungeon[i][n - 1], 0);
		}
		for (int j = n - 2; j >= 0; --j) {
			dungeon[m - 1][j] = max(dungeon[m - 1][j + 1] - dungeon[m - 1][j], 0);
		}
		for (int i = m - 2; i >= 0; --i) {
			for (int j = n - 2; j >= 0; --j) {
				dungeon[i][j] = max(min(dungeon[i][j + 1], dungeon[i + 1][j]) - dungeon[i][j], 0);
			}
		}
		return dungeon[0][0] + 1;
	}
	
	private int min(int a, int b) {
		if(a < b) {
			return a;
		}
		return b;
	}

	private int max(int a, int b) {
		if(a > b) {
			return a;
		}
		return b;
	}
}


参考:http://www.cnblogs.com/easonliu/p/4237644.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值