198. House Robber 打家劫舍

題目鏈接
tag:

  • Easy;
  • DP;

question:
??You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.

Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.

Example 1:

Input: [1,2,3,1]
Output: 4
Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).
Total amount you can rob = 1 + 3 = 4.

Example 2:

Input: [2,7,9,3,1]
Output: 12
Explanation: Rob house 1 (money = 2), rob house 3 (money = 9) and rob house 5 (money = 1).
Total amount you can rob = 2 + 9 + 1 = 12.

思路:
??這道題的本質相當于在一列數組中取出一個或多個不相鄰數,使其和最大。那么我們對于這類求極值的問題首先考慮動態規劃Dynamic Programming來解,我們維護一個一位數組dp,其中dp[i]表示到i位置時不相鄰數能形成的最大和,那么狀態轉移方程怎么寫呢,我們先拿一個簡單的例子來分析一下,比如說nums為{3, 2, 1, 5},那么我們來看我們的dp數組應該是什么樣的,首先dp[0]=3沒啥疑問,再看dp[1]是多少呢,由于3比2大,所以我們搶第一個房子的3,當前房子的2不搶,所以dp[1]=3,那么再來看dp[2],由于不能搶相鄰的,所以我們可以用再前面的一個的dp值加上當前的房間值,和當前房間的前面一個dp值比較,取較大值當做當前dp值,所以我們可以得到狀態轉移方程dp[i] = max(num[i] + dp[i - 2], dp[i - 1]), 由此看出我們需要初始化dp[0]和dp[1],其中dp[0]即為num[0],dp[1]此時應該為max(num[0], num[1]),代碼如下:

// DP
class Solution {
public:
    int rob(vector<int> &num) {
        if (num.size() <= 1) 
            return num.empty() ? 0 : num[0];
        vector<int> dp = {num[0], max(num[0], num[1])};
        for (int i=2; i<num.size(); ++i) 
            dp.push_back(max(num[i] + dp[i-2], dp[i-1]));
        return dp.back();
    }
};
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。