Leetcode--174. 地下城游戏
一些惡魔抓住了公主(P)并將她關在了地下城的右下角。地下城是由?M x N 個房間組成的二維網格。我們英勇的騎士(K)最初被安置在左上角的房間里,他必須穿過地下城并通過對抗惡魔來拯救公主。
騎士的初始健康點數為一個正整數。如果他的健康點數在某一時刻降至 0 或以下,他會立即死亡。
有些房間由惡魔守衛,因此騎士在進入這些房間時會失去健康點數(若房間里的值為負整數,則表示騎士將損失健康點數);其他房間要么是空的(房間里的值為 0),要么包含增加騎士健康點數的魔法球(若房間里的值為正整數,則表示騎士將增加健康點數)。
為了盡快到達公主,騎士決定每次只向右或向下移動一步。
?
編寫一個函數來計算確保騎士能夠拯救到公主所需的最低初始健康點數。
例如,考慮到如下布局的地下城,如果騎士遵循最佳路徑 右 -> 右 -> 下 -> 下,則騎士的初始健康點數至少為 7。
-2 (K)?? ?-3?? ?3
-5?? ?-10?? ?1
10?? ?30?? ?-5 (P)
?
說明:
騎士的健康點數沒有上限。
任何房間都可能對騎士的健康點數造成威脅,也可能增加騎士的健康點數,包括騎士進入的左上角房間以及公主被監禁的右下角房間。
?
這題想了兩天,最后也沒搞出來,看了大佬的思路,才會的。。。。
這道題意思就是從左上角如何到右下角,只能向右,向下,在這之間有加血,有扣血,如何初始血量使得正好到達。
其實我們可以倒過來想。從右下角保持多少血量能到達左上角。
我們用 dp[i][j]表示在i,j位置最少需要的血量
動態方程:dp[i][j] = max(1, min(dp[i+1][j], dp[i][j+1]) - dungeon[i][j])
最后一行和最后一列做特殊處理
題中給的案例是:
-2? -3? ? ?3?
-5? -10? ?1
10? 30? ?-5
那么從最后一點開始推測,最后一點需要6點血才可以
那么他上面那一行的1處因為可以加一點血,所以到那有五點血就可以
最后推導出來各點的血量就是:
7? ?5? ?2
6? ?11? 5
1? ?1? ?6
提交的代碼:
class Solution {
? ? public int calculateMinimumHP(int[][] dungeon) {
? ? int m = dungeon.length;
?? ??? ?int n = dungeon[0].length;
?? ??? ?int[][] dp = new int[m][n];
?? ??? ?int i,j;
?? ??? ?if(dungeon[m-1][n-1]<0)
?? ??? ?{
?? ??? ??? ?dp[m-1][n-1]=1+java.lang.Math.abs(dungeon[m-1][n-1]);
?? ??? ?}
?? ??? ?else
?? ??? ?{
?? ??? ??? ?dp[m-1][n-1]=1;
?? ??? ?}
?? ??? ?for(i=m-1;i>=0;i--)
?? ??? ?{
?? ??? ??? ?for(j=n-1;j>=0;j--)
?? ??? ??? ?{
?? ??? ??? ??? ?if(i==m-1&&j!=n-1)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?dp[i][j] = java.lang.Math.max(1,dp[i][j+1]-dungeon[i][j]);
?? ??? ??? ??? ?}
?? ??? ??? ??? ?else if(i!=m-1&&j==n-1)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?dp[i][j] = java.lang.Math.max(1,dp[i+1][j]-dungeon[i][j]);
?? ??? ??? ??? ?}
?? ??? ??? ??? ?else if(i!=m-1&&j!=n-1)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?dp[i][j] = java.lang.Math.max(1,java.lang.Math.min(dp[i+1][j],dp[i][j+1])-dungeon[i][j]);
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ??? ?
?? ??? ?}
?? ??? ?return dp[0][0];
? ? }
}
完整的代碼:
public class Solution174 {
?? ?public static int calculateMinimumHP(int[][] dungeon) {
?? ??? ?int m = dungeon.length;
?? ??? ?int n = dungeon[0].length;
?? ??? ?int[][] dp = new int[m][n];
?? ??? ?int i,j;
?? ??? ?if(dungeon[m-1][n-1]<0)
?? ??? ?{
?? ??? ??? ?dp[m-1][n-1]=1+java.lang.Math.abs(dungeon[m-1][n-1]);
?? ??? ?}
?? ??? ?else
?? ??? ?{
?? ??? ??? ?dp[m-1][n-1]=1;
?? ??? ?}
?? ??? ?for(i=m-1;i>=0;i--)
?? ??? ?{
?? ??? ??? ?for(j=n-1;j>=0;j--)
?? ??? ??? ?{
?? ??? ??? ??? ?if(i==m-1&&j!=n-1)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?dp[i][j] = java.lang.Math.max(1,dp[i][j+1]-dungeon[i][j]);
?? ??? ??? ??? ?}
?? ??? ??? ??? ?else if(i!=m-1&&j==n-1)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?dp[i][j] = java.lang.Math.max(1,dp[i+1][j]-dungeon[i][j]);
?? ??? ??? ??? ?}
?? ??? ??? ??? ?else if(i!=m-1&&j!=n-1)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?dp[i][j] = java.lang.Math.max(1,java.lang.Math.min(dp[i+1][j],dp[i][j+1])-dungeon[i][j]);
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ??? ?
?? ??? ?}
?? ??? ?return dp[0][0];
? ? ? ??
? ? }
?? ?public static void main(String[] args)
?? ?{
?? ??? ?int[][] nums = {{-2,-3,3},{-5,-10,1},{10,30,-5}};
?? ??? ?//int[][] nums = {{0,0,0},{1,1,-1}};
?? ??? ?//int[][] nums = {{-200}};
?? ??? ?System.out.println(calculateMinimumHP(nums));
?? ?}
}
?
總結
以上是生活随笔為你收集整理的Leetcode--174. 地下城游戏的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机组成原理——计算机系统的性能指标(
- 下一篇: Leetcode--347. 前k个高频