LeetCode每日一題 174 地下城遊戲

2021-10-08 01:55:00 字數 1569 閱讀 5361

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

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

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

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

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

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

-2(k)-33

-5-10110

30-5§

說明:騎士的健康點數沒有上限。

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

(1)dfs搜尋,每次只能往左或者往右。不過很容易就超時了。

(2)dp演算法。

有兩個思路,乙個是正向dp,乙個是方向dp

1、正向dp

起始的最低hp min_hp = 1,最高需要的hp max_hp 是所有負值相加,取反加1(因為最差情況下就是把所有的負值得點都經過了)。

因此這時候可以使用二分搜尋+正向dp的解法。

假設當前所需要的hp是mid_hp = (min_hp + max_hp) / 2;

如果mid_hp血量的時候只要能夠到達終點,則max_hp = mid_hp

如果mid_hp血量的時候不能達到終點,則min_hp = mid_hp + 1

2、反向dp

令dp[i][j] 為(i,j)這個點到底終點所需要的最低hp,

則dp[i][j] = min(dp[i+1][j], dp[i][j+1]) - dungeon[i][j], 如果dp[i][j]小於或等於0,則說明(i,j)這個點到終點可達,只需要dp[i][j] = 1即可。

正向dp的**

class

solution

} max_need_hp +=1

;while

(min_need_hp < max_need_hp)

return max_need_hp;

}bool

canrearchend

(vectorint>>

& dungeon,

int hp)

else

if(i ==0)

else

if(j ==0)

else

if(dp[i]

[j]<=0)

dp[i]

[j]=

-1e9;}

}return dp[m-1]

[n-1

]>0;

}};

每日一題 LeetCode

在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數。示例 1 輸入 7,5,6,4 輸出 5 限制 0 陣列長度 50000 思想是 分治演算法 所有的 逆序對 於 3 個部分 左邊區間的逆序對 右邊區間的逆序對 橫跨兩個區間的...

LeetCode每日一題(題1028)

最近在刷leetcode每日一題,每次做完之後總能有些收穫,所以想著不如每天寫個部落格記錄一下做的題目的解法以及自己寫的時候問題出在 從先序遍歷還原二叉樹 題目大意 給出乙個字串 1 2 3 4 5 6 7 1代表節點的值,前面的 個數代表節點的深度。如果只有乙個子節點,保證這個節點為左子節點。返回...

LeetCode每日一題(題139)

題目 題目大意 給出乙個字串s和乙個字串陣列words,判斷s是否能夠拆分成多個words中的字串。分析 這道題比較簡單的方式應該是採用動態規劃來做。對於任意乙個字串中的區間,可以判斷該區間組成的字串是否在字典中,如果是,則這個區間的真假取決於前面那個區間的真假。給出狀態轉移方程dp i dp j ...