leetcode筆記系列 174 地下城遊戲

2022-09-11 04:24:13 字數 2022 閱讀 4062

題目描述如下:

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

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

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

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

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

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

-2(k)-33

-5101-9

-10-5(p)

說明:

解題思路:

這是一道比較典型的動態規劃問題。一開始我想的比較複雜,因為需要考慮騎士到達每乙個房間與惡魔打鬥的時候,確保不會掛,也就是其體力大於零。後來網上參考了其他大佬寫的部落格,發現,其實從公主的位置開始倒推,也就是按照從下往上、從左往右的方式處理,會更好一些。因為我們不知道騎士在起點處到底需要多少體力,但是我們知道,從某個房間,去下乙個房間需要多少體力。所以,還是拿題目給的例子來分析,這是乙個3*3的地牢,騎士最後所到達的有公主的房間,需要消耗5點體力。在此之前,如果騎士到達公主左邊的房間,需要10+5=15點體力,才能順利解救公主;或者,騎士到達的是公主上面的房間,則一共需要4點體力。我們再往前看,假設騎士剛進入了地牢正中間的這個房間。騎士在該房間不消耗體力,並撿到了10點體力。之後騎士將面臨兩個選擇:1.去下面的房間,然後消耗15點體力解救公主;2.去右邊的房間,消耗4點體力。我們肯定選2對吧。由於中間的房間可以撿到10點體力,之後再消耗4點體力,多剩了6點體力。也就是說,騎士從正中間的房間走到最後,相當於是不用消耗體力的。

解釋到這裡,遞推公式就出來了:hp[i][j] = max(0,min(hp[i+1][j], hp[i][j+1])-dungeon[i][j]),其中hp[i][j]指從牢中房間ij開始,走到最後所需要消耗的體力(大於等於0)。dungeon[i][j]表示在房間ij中需要消耗的體力。遞推到最後,hp[0][0]的值就表示,從地牢左上角到地牢右下角所需要消耗的最小體力。因此,騎士進入地牢,保證有1+hp[0][0]的體力,就ok了。

下面上**:

1

public

int calculateminimumhp1(int

dungeon)

12int right = (j==m-1)?integer.max_value:hp[i][j+1];

13int down = (i==n-1)?integer.max_value:hp[i+1][j];

14 hp[i][j] = math.max(0, math.min(right,down)-dungeon[i][j]);15}

16}17return hp[0][0]+1;

18 }

注意第8-13用來處理邊界問題。其實,還可以繼續優化,只用一維陣列hp,就可以達到效果:

1

public

int calculateminimumhp2(int

dungeon)

12int right = (j==m-1)?integer.max_value:db[j+1];

13int down = (i==n-1)?integer.max_value:db[j];

14 db[j] = math.max(0, math.min(right,down)-dungeon[i][j]);15}

16}17return db[0]+1;

18 }

leetcode筆記系列 42 接雨水

給定 n 個非負整數表示每個寬度為 1 的柱子的高度圖,計算按此排列的柱子,下雨之後能接多少雨水。解題思路是,找到所有柱子中最高的 記為max 然後從兩邊,分別向最高的柱子靠攏。遍歷的過程中,需要記錄當前除max外最高的柱子 記為root max和root之間的空間,減掉這之間的柱子高度,即為所能接...

LeetCode 174 地下城遊戲

一些惡魔抓住了公主 p 並將她關在了地下城的右下角。地下城是由 m x n 個房間組成的二維網格。我們英勇的騎士 k 最初被安置在左上角的房間裡,他必須穿過地下城並通過對抗惡魔來拯救公主。騎士的初始健康點數為乙個正整數。如果他的健康點數在某一時刻降至 0 或以下,他會立即死亡。有些房間由惡魔守衛,因...

LeetCode174 地下城遊戲

一些惡魔抓住了公主 p 並將她關在了地下城的右下角。地下城是由 m x n 個房間組成的二維網格。我們英勇的騎士 k 最初被安置在左上角的房間裡,他必須穿過地下城並通過對抗惡魔來拯救公主。騎士的初始健康點數為乙個正整數。如果他的健康點數在某一時刻降至 0 或以下,他會立即死亡。有些房間由惡魔守衛,因...