1. 程式人生 > >LeetCode 174.Dungeon Game (地下城遊戲)

LeetCode 174.Dungeon Game (地下城遊戲)

題目描述:

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

騎士的初始健康點數為一個正整數。如果他的健康點數在某一時刻降至 0 或以下,他會立即死亡。

有些房間由惡魔守衛,因此騎士在進入這些房間時會失去健康點數(若房間裡的值為負整數,則表示騎士將損失健康點數);其他房間要麼是空的(房間裡的值為 0),要麼包含增加騎士健康點數的魔法球(若房間裡的值為正整數,則表示騎士將增加健康點數)。

為了儘快到達公主,騎士決定每次只向右或向下移動一步。

 

編寫一個函式來計算確保騎士能夠拯救到公主所需的最低初始健康點數。

例如,考慮到如下佈局的地下城,如果騎士遵循最佳路徑 右 -> 右 -> 下 -> 下,則騎士的初始健康點數至少為 7

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

 

說明:

  • 騎士的健康點數沒有上限。

  • 任何房間都可能對騎士的健康點數造成威脅,也可能增加騎士的健康點數,包括騎士進入的左上角房間以及公主被監禁的右下角房間。

 

 

解題思路:

與之前遇到的不同路徑的題是相同的思路:

不同路徑

不同路徑 II

 

使用一個二維陣列,從右下到左上更新每個點所需的最小健康點數。

 

AC C++ Solution:

class Solution {            //使用hp[i][j]來儲存位置(i,j)所需的最小hp,然後從右下角到左上角計算
public:
    int calculateMinimumHP(vector<vector<int> > &dungeon) {
        int M = dungeon.size();     //行數
        int N = dungeon[0].size();  //列數
        // hp[i][j] represents the min hp needed at position (i, j)
        // Add dummy row and column at bottom and right side
        vector<vector<int> > hp(M + 1, vector<int>(N + 1, INT_MAX));    //多初始化一行一列,作為起點
        hp[M][N - 1] = 1;
        hp[M - 1][N] = 1;
        for (int i = M - 1; i >= 0; i--) {
            for (int j = N - 1; j >= 0; j--) {
                int need = min(hp[i + 1][j], hp[i][j + 1]) - dungeon[i][j];     //每個點所需hp是min(下方,右方) - 當前點   
                hp[i][j] = need <= 0 ? 1 : need;
            }
        }
        return hp[0][0];
    }
};