!經(jīng)典DP!
你是一個(gè)專(zhuān)業(yè)的小偷,計(jì)劃偷竊沿街的房屋。每間房?jī)?nèi)都藏有一定的現(xiàn)金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統(tǒng),如果 兩間相鄰的房屋在同一晚上被小偷闖入,系統(tǒng)會(huì)自動(dòng)報(bào)警。
給定一個(gè)代表每個(gè)房屋存放金額的非負(fù)整數(shù)數(shù)組,計(jì)算你不觸動(dòng)警報(bào)裝置的情況下 ,一夜之內(nèi)能夠偷竊到的最高金額。
示例 1:
輸入:[1,2,3,1]
輸出:4
解釋?zhuān)和蹈` 1 號(hào)房屋 (金額 = 1) ,然后偷竊 3 號(hào)房屋 (金額 = 3)。
偷竊到的最高金額 = 1 + 3 = 4 。
示例 2:
輸入:[2,7,9,3,1]
輸出:12
解釋?zhuān)和蹈` 1 號(hào)房屋 (金額 = 2), 偷竊 3 號(hào)房屋 (金額 = 9),接著偷竊 5 號(hào)房屋 (金額 = 1)。
偷竊到的最高金額 = 2 + 9 + 1 = 12 。
提示:
- 1 <=
nums.length
<= 100 - 0 <=
nums[i]
<= 400
動(dòng)態(tài)規(guī)劃的的四個(gè)解題步驟是:
-
定義子問(wèn)題: 總問(wèn)題:搶N個(gè)房子 – > 子問(wèn)題:搶 K個(gè)房子
-
寫(xiě)出子問(wèn)題的遞推關(guān)系:第k個(gè)房子要么被搶要么不被搶?zhuān)篎(k) = max(F(k-1), nums[k] + F(k-2))
(只與前兩個(gè)房子的最大金額有關(guān)——空間優(yōu)化,N長(zhǎng)數(shù)組變成2個(gè)變量) -
確定 DP 數(shù)組的計(jì)算順序:
動(dòng)態(tài)規(guī)劃有兩種計(jì)算順序,一種是自頂向下的、使用備忘錄的遞歸方法,一種是自底向上的、使用 dp 數(shù)組的循環(huán)方法。不過(guò)在普通的動(dòng)態(tài)規(guī)劃題目中,99% 的情況我們都不需要用到備忘錄方法,所以我們最好堅(jiān)持用自底向上的 dp 數(shù)組
DP 數(shù)組中的依賴關(guān)系都是向右指的,DP 數(shù)組的計(jì)算順序就是從左向右。這樣我們可以保證,計(jì)算一個(gè)子問(wèn)題的時(shí)候,它所依賴的那些子問(wèn)題已經(jīng)計(jì)算出來(lái)了。 -
空間優(yōu)化(可選)
題解1 DP1
class Solution {
public:
int rob(vector<int>& nums) {
int s = nums.size();
vector<int> dp(s+1, 0);
dp[1] = nums[0];
for(int i = 1; i < s; i++){
dp[i+1] = max(dp[i], dp[i-1]+nums[i]);
}
return dp[s];
}
};
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-725323.html
題解2 DP2
class Solution {
public:
int rob(vector<int>& nums) {
int s = nums.size();
if(1 == s) return nums[0];
int first = nums[0];
int sec = max(nums[0], nums[1]);
for(int i = 2; i < s; i++){
int tmp = sec;
// sec是i-1的情況, first是i-2
sec = max(first+nums[i], sec);
first = tmp;
}
return sec;
}
};
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-725323.html
到了這里,關(guān)于53 打家劫舍的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!