(Meituan) Dynamic planning, house robbery!

I have prepared 1,000 e-books and 100 high-definition mind maps in various fields of computer, and I will reply to [Resources] after paying attention to get it! You can even reply [introduction] to join the BAT introduction group!

(Meituan) Dynamic planning, house robbery!

In the first two articles, we have studied the problems of " triangular minimum path sum " and " rectangular minimum path sum ". I believe that we have mastered the problem-solving methods of this type of problem. As long as we clarify the definition of the state , we can basically solve it smoothly.

In this section, we will return to a simpler topic, the purpose is to analyze the process of state definition, and give an example of how much trouble it will cause us if the state definition is wrong! Hope you don’t take it lightly!

01, topic analysis


Question 198: House Robbery


You are a professional thief, planning to steal houses along the street. There is a certain amount of cash hidden in each room. The only constraint that affects your theft is that the adjacent houses are equipped with interconnected anti-theft systems. If two adjacent houses are broken into by a thief at the same night, the system will automatically alarm .


Given an array of non-negative integers representing the amount of storage in each house, calculate the highest amount you can steal without triggering the alarm device.

Example 1:

输入: [1,2,3,1]
输出: 4
解释: 偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
  偷窃到的最高金额 = 1 + 3 = 4 。

Example 2:

输入: [2,7,9,3,1]
输出: 12
解释: 偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
     偷窃到的最高金额 = 2 + 9 + 1 = 12 。

This question mainly analyzes the process of state definition! It is strongly recommended to study the previous content first!

In order to achieve the best learning effect!

02, topic illustration


Assuming there are i houses, we may define two states:

  • dp[i]: The maximum benefit obtained when stealing the i-th house
  • dp[i]: the maximum benefit obtained when stealing to the i-th house

If we define it as state 1, because we have no way to know which houses the thief stolen when the maximum amount was obtained . So we need to find the maximum value among all states in order to find our final answer. which is:

max(dp[0],dp[1],.....,dp[len(dp)-1])

If we define it as state two, because the thief will definitely steal from the front to the end (emphasis: stealing to the i-th room does not mean that the thief wants to obtain property from the i-th room). So our final answer is easy to determine. which is:

dp[i]

Now we analyze the state transition equations under these two state definitions:

If it is the first state, the maximum amount that can be obtained when stealing includes the i-th room, we are equivalent to finding the maximum amount that can be obtained when stealing each house . For example, in the picture below, we need to find dp[4], which is the maximum amount that can be obtained when the house 9 is stolen.
(Meituan) Dynamic planning, house robbery!

Then we need to find the maximum amount that can be obtained in the two paragraphs that are not adjacent to 9.
(Meituan) Dynamic planning, house robbery!

We find that the problem has entered a vicious circle, because if we want to find the maximum amount that can be stolen at the two ends that are not adjacent to 9, according to the definition of dp[i], we need to analyze the stealing of each of the two paragraphs The best benefit you can get when you house! It's scary to think about it! So we give up the definition of this state.

If it is the second state, the maximum benefit that can be obtained when the i-th house is stolen. Then we can think that since it is not possible to break into adjacent houses, the maximum value that can be stolen from house i is either the maximum value that can be stolen from house i-1 or the maximum value that can be stolen from house i-2. The value plus the value of the current house, and the maximum value between the two, namely:

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

If you don’t understand, you can look at the picture below:

(It is equivalent to the little thief carrying a backpack with the stolen property inside, and every time he arrives at the door of the next room, he chooses whether to steal or not.)

(Meituan) Dynamic planning, house robbery!

03, GO language example


After the analysis is completed, we solve the problem according to the second state definition:

func rob(nums []int) int {
    if len(nums) < 1 {
        return 0
    }
    if len(nums) == 1 {
        return nums[0]
    }
    if len(nums) == 2 {
        return max(nums[0],nums[1])
    }
    dp := make([]int, len(nums))
    dp[0] = nums[0]
    dp[1] = max(nums[0],nums[1])
    for i := 2; i < len(nums); i++ {
        dp[i] = max(dp[i-2]+nums[i],dp[i-1])
    }
    return dp[len(dp)-1]
}

func max(a,b int) int {
    if a > b {
        return a
    }
    return b
}

operation result:
(Meituan) Dynamic planning, house robbery!

Similarly, running the above code, we find that the memory used is too large. Is there any way to compress memory? It is easy for us to think that in the process of the thief stealing, it is impossible to turn back to the room that he has already stolen! (Too stupid) The thief only needs to move his belongings to the next room every time!

According to the above ideas, the optimized code is as follows:

func rob(nums []int) int {
    if len(nums) < 1 {
        return 0
    }
    if len(nums) == 1 {
        return nums[0]
    }
    if len(nums) == 2 {
        return max(nums[0],nums[1])
    }
    nums[1] = max(nums[0],nums[1])
    for i := 2; i < len(nums); i++ {
        nums[i] = max(nums[i-2]+nums[i],nums[i-1])
    }
    return nums[len(nums)-1]
}

func max(a,b int) int {
    if a > b {
        return a
    }
    return b
}

operation result:

(Meituan) Dynamic planning, house robbery!
java:

class Solution {
    public int rob(int[] nums) {
        if (nums.length < 1) {
            return 0;
        } 

        if (nums.length == 1) {
            return nums[0];
        }

        if (nums.length == 2) {
            return Math.max(nums[0],nums[1]);
        }

        nums[1] = Math.max(nums[0], nums[1]);

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

operation result:

(Meituan) Dynamic planning, house robbery!

Guess you like

Origin blog.51cto.com/15076236/2608565