一些惡魔抓住了公主(p)並將她關在了地下城的右下角。地下城是由 m x n 個房間組成的二維網格。我們英勇的騎士(k)最初被安置在左上角的房間裡,他必須穿過地下城並通過對抗惡魔來拯救公主。
騎士的初始健康點數為乙個正整數。如果他的健康點數在某一時刻降至 0 或以下,他會立即死亡。
有些房間由惡魔守衛,因此騎士在進入這些房間時會失去健康點數(若房間裡的值為負整數,則表示騎士將損失健康點數);其他房間要麼是空的(房間裡的值為 0),要麼包含增加騎士健康點數的魔法球(若房間裡的值為正整數,則表示騎士將增加健康點數)。
為了盡快到達公主,騎士決定每次只向右或向下移動一步。
編寫乙個函式來計算確保騎士能夠拯救到公主所需的最低初始健康點數。
例如,考慮到如下布局的地下城,如果騎士遵循最佳路徑右 -> 右 -> 下 -> 下
,則騎士的初始健康點數至少為7。
說明:騎士的健康點數沒有上限。
任何房間都可能對騎士的健康點數造成威脅,也可能增加騎士的健康點數,包括騎士進入的左上角房間以及公主被監禁的右下角房間。
問題:從左上開始,還是從右下開始。
自己做的時候從左上開始的,但是只能通過一半的例子。
解答:我們的子問題是「從i,j到達終點需要的最小生命值」,它依賴於從i,j右下側的路徑;動態規劃類似於數學歸納,我們需要找到base situation,對於我們要求的問題,就是從右下角開始(即在公主處我們需要的答案是確定的),所以是從右下到左上遞推。如果從左上開始推,我們並不是基於已知解的,相當於在做一次dfs完全搜尋,自然需要記錄所有中間狀態(到達每個點的最小值與到達每個點剩餘的生命值)。
剩下的看官方題解就可以了。
另附上自己的**:
public static int calculateminimumhp(int dungeon)
int row = dungeon.length;
int col = dungeon[0].length;
int dp = new int[row][col];
if (dungeon[row - 1][col - 1] >= 0)
dp[row - 1][col - 1] = 1;
else
dp[row - 1][col - 1] = 1 - dungeon[row - 1][col - 1];
// 最後一行
for (int i = col - 2; i >= 0; i--)
// 最後一列
for (int i = row - 2; i >= 0; i--)
for (int i = row - 2; i >= 0; i--)
}return dp[0][0];
}
174 地下城遊戲
一些惡魔抓住了公主 p 並將她關在了地下城的右下角。地下城是由 m x n 個房間組成的二維網格。我們英勇的騎士 k 最初被安置在左上角的房間裡,他必須穿過地下城並通過對抗惡魔來拯救公主。騎士的初始健康點數為乙個正整數。如果他的健康點數在某一時刻降至 0 或以下,他會立即死亡。有些房間由惡魔守衛,因...
174 地下城遊戲
174.地下城遊戲 一些惡魔抓住了公主 p 並將她關在了地下城的右下角。地下城是由 m x n 個房間組成的二維網格。我們英勇的騎士 k 最初被安置在左上角的房間裡,他必須穿過地下城並通過對抗惡魔來拯救公主。騎士的初始健康點數為乙個正整數。如果他的健康點數在某一時刻降至 0 或以下,他會立即死亡。有...
174 地下城遊戲
一些惡魔抓住了公主 p 並將她關在了地下城的右下角。地下城是由 m x n 個房間組成的二維網格。我們英勇的騎士 k 最初被安置在左上角的房間裡,他必須穿過地下城並通過對抗惡魔來拯救公主。騎士的初始健康點數為乙個正整數。如果他的健康點數在某一時刻降至 0 或以下,他會立即死亡。有些房間由惡魔守衛,因...