leetcode174. 地下城遊戲

一些惡魔抓住了公主(P)並將她關在了地下城的右下角。地下城是由 M x N 個房間組成的二維網格。我們英勇的騎士(K)最初被安置在左上角的房間裏,他必須穿過地下城並通過對抗惡魔來拯救公主。

騎士的初始健康點數爲一個正整數。如果他的健康點數在某一時刻降至 0 或以下,他會立即死亡。
有些房間由惡魔守衛,因此騎士在進入這些房間時會失去健康點數(若房間裏的值爲負整數,則表示騎士將損失健康點數);其他房間要麼是空的(房間裏的值爲 0),要麼包含增加騎士健康點數的魔法球(若房間裏的值爲正整數,則表示騎士將增加健康點數)。
爲了儘快到達公主,騎士決定每次只向右或向下移動一步。
編寫一個函數來計算確保騎士能夠拯救到公主所需的最低初始健康點數。
例如,考慮到如下佈局的地下城,如果騎士遵循最佳路徑 右 -> 右 -> 下 -> 下,則騎士的初始健康點數至少爲 7。
-2 (K) -3 3
-5 -10 1
10 30 -5
說明:
騎士的健康點數沒有上限。
任何房間都可能對騎士的健康點數造成威脅,也可能增加騎士的健康點數,包括騎士進入的左上角房間以及公主被監禁的右下角房間。

動態規劃的題,能想明白dp各位置代表什麼就很簡單,注意不僅僅最後能到達,而且在每一個地方騎士的生命值都大於等於1:

class Solution:
    def calculateMinimumHP(self, dungeon: List[List[int]]) -> int:
        x, y = len(dungeon), len(dungeon[0])
        dp = [[0]*y for _ in range(x)]  # 能到達最後在這個位置的最小體力值,>=1
        dp[-1][-1] = max(1, 1-dungeon[-1][-1])
        for j in range(y-2, -1, -1):  # 最後一行
            dp[-1][j] = max(1, dp[-1][j+1]-dungeon[-1][j])
        for i in range(x-2, -1, -1):
            dp[i][-1] = max(1, dp[i+1][-1]-dungeon[i][-1])
        for j in range(y-2, -1, -1):  # 從右到左
            for i in range(x-2, -1, -1):  # 從下到上
                # 找這個位置下邊或右邊需要的較少體力值
                dp[i][j] = max(1, min(dp[i][j+1], dp[i+1][j])-dungeon[i][j])
        return dp[0][0]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章