简体   繁体   中英

Reason for such initialization of DP array

I am solving a question from LeetCode.com. The question is like this:

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.

After thinking about it for a while, I could come up with the following relation, which is correct:

dp[i] = max(dp[i-2]+nums[i], dp[i-1]);

However, I couldn't initialize the dp[] array. In the solutions it has been initialized like this:

dp[0]=nums[0];
dp[1]=max(nums[0],nums[1]);

Isn't this incorrect? Because if nums[0]>nums[1] , then doesn't it imply robbing the same house (because we initialize both dp[0] and dp[1] to the same value?) Even if we assume that nums[1]>nums[0] , wouldn't nums[0] and nums[1] be consecutive houses?

Full code (if required) is below:

class Solution {
public:
    int rob(vector<int>& nums) {
        if(nums.empty())
            return 0;

        vector<int> dp(nums.size());
        dp[0]=nums[0];
        dp[1]=max(nums[0], nums[1]);

        for(int i=2; i<nums.size(); i++) {
            dp[i] = max(nums[i]+dp[i-2], dp[i-1]);
        }

        return dp[nums.size()-1];
    }
};

In the solution given think of dp[i] as "the maximum amount of money you can rob from i+1 houses without alerting the police" and look at each i as a separate case. If there is 1 house ( i == 0 ) then you can only steal from that one house. If there are two houses ( i == 1 ) then the most you can steal is the max from either house ( nums[0] or nums[1] ). The way I did it was:

int n = nums.size();
int dp[n+1]; // max $ you can rob from i houses with altering police
dp[0] = 0; // no houses, no money
dp[1] = nums[0];
for (int i = 2; i <= n; ++i) {
  dp[i] = max(dp[i - 1], nums[i - 1] + dp[i - 2]);
}
return dp[n];

which returns the maximum amount of money you can steal from i houses (not i+1 ), which I think is easier to understand.

If I understand correctly your question reduces to: Because if nums[0]>nums[1], then doesn't it imply robbing the same house (because we initialize both dp[0] and dp[1] to the same value?) .

The answer is no, it doesn't imply robbing the same house. it implies not robbing the house 1 because house 0 was robbed. And house 0 was robbed because it contained more money and you had to choose between robbing either house 0 or house 1 (which had less money).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM