[leetcode 198] House robbery

topic

Link to the topic: https://leetcode.cn/problems/house-robber/

insert image description here

solution

Simply put, adjacent items cannot be taken at the same time.

method one

We use choose[i] to express (must take) the maximum value that can be obtained from the i-th item, and ignore[i] to indicate to give up (must give up) the maximum value that can be obtained from the i-th item.

ignore[i] may be larger than choose[i], because choose[i] must take the i-th item, so it cannot take the i-1-th item, but the i-1-th item may be of great value.

The state transition equation is as follows

must take i { take i − 2 : choose [ i − 2 ] + nums [ i ] release i − 2 : ignore [ i − 2 ] + nums [ i ] must take i\left\{ \begin{aligned} & take i-2: &choose[i-2]+nums[i]\\ &flash i-2: &ignore[i-2]+nums[i] \\ \end{aligned} \right.i must be taken{ take i2radiation i2choose[i2]+nums[i]ignore[i2]+nums[i]

must give up i { take i − 1 : choose [ i − 1 ] take i − 2 : choose [ i − 2 ] must give up i\left\{ \begin{aligned} take i-1: &choose[i-1]\ \ Take i-2: &choose[i-2] \\ \end{aligned} \right.must give up i{ take i1take i2choose[i1]choose[i2]

code show as below

class Solution {
    
    
public:
    int rob(vector<int>& nums) {
    
    
        int len = nums.size();
        if (len == 1) {
    
    
            return nums[0];
        }
        vector<int> choose(len);
        vector<int> ignore(len);
        int ans = 0;
        choose[0] = nums[0]; choose[1] = nums[1];
        ignore[0] = 0;       ignore[1] = nums[0];
        for (int i = 0; i < 2; i++) {
    
    
            ans = max(choose[i], ignore[i]);
        }
        for (int i = 2; i < len; i++) {
    
    
            choose[i] = max(choose[i-2], ignore[i-2]) + nums[i];
            ignore[i] = max(choose[i-1], choose[i-2]);
            ans = max(choose[i], ignore[i]);
        }
        return ans;
    }
};

Method Two

In fact, the two states mentioned above can be combined, that is, we only use an array dp, and dp[i] represents the maximum value that can be obtained up to the i-th item, and we can choose the i-th item or give it up.

d p [ i ] { 取 i : d p [ i − 2 ] + n u m s [ i ] 不取 i : d p [ i − 1 ] dp[i]\left\{ \begin{aligned} &取i:&dp[i-2]+nums[i]\\ &不取i:&dp[i-1] \\ \end{aligned} \right. dp[i]{ Takei : _Do not take i :dp[i2]+nums[i]dp[i1]

When i=1, dp[-1] can be treated as 0 to ensure that the result is correct when i=1.

code show as below

class Solution {
    
    
public:
    int rob(vector<int>& nums) {
    
    
        int len = nums.size();
        if (len == 1) {
    
    
            return nums[0];
        }
        vector<int> dp(len);
        dp[0] = nums[0];
        dp[1] = max(nums[0], nums[1]);
        for (int i = 2; i < len; i++) {
    
    
            dp[i] = max(dp[i-2]+nums[i], dp[i-1]);
        }
        return dp[len-1];
    }
};

Topic upgrade (Meituan 23 spring)

After the i-th user is selected, i-2, i-1, i+1, and i+2 cannot be selected. What is the maximum value that can be stolen?

We only use an array dp, dp[i] represents the maximum value that can be obtained up to the i-th item, and we can choose or give up the i-th item.

d p [ i ] { 取 i : d p [ i − 3 ] + n u m s [ i ] 不取 i : d p [ i − 1 ] dp[i]\left\{ \begin{aligned} &取i:&dp[i-3]+nums[i]\\ &不取i:&dp[i-1] \\ \end{aligned} \right. dp[i]{ Takei : _Do not take i :dp[i3]+nums[i]dp[i1]

During initialization, the result is guaranteed to be correct when i=1 and i=2.

Topic upgrade (ant 23 spring)

You can steal 2 consecutive households, but you cannot steal 3 consecutive households, but steal at least one of the 3 consecutive households. Ask the maximum value that can be stolen?

We only use an array dp, dp[i] represents the maximum value that can be obtained up to the i-th item, and we can choose or give up the i-th item.

d p [ i ] { _   0   1   1 : d p [ i − 3 ] + n u m s [ i − 1 ] + n u m s [ i ] _   1   0   1 : d p [ i − 3 ] + n u m s [ i − 2 ] + n u m s [ i ] _   _   _   0 : d p [ i − 1 ] dp[i]\left\{ \begin{aligned} &\_\ 0\ 1\ 1:&dp[i-3]+nums[i-1]+nums[i]\\ &\_\ 1\ 0\ 1:&dp[i-3]+nums[i-2]+nums[i]\\ &\_\ \_\ \_\ 0:&dp[i-1] \\ \end{aligned} \right. dp[i] _ 0 1 1_ 1 0 1_ _ _ 0dp[i3]+nums[i1]+nums[i]dp[i3]+nums[i2]+nums[i]dp[i1]

During initialization, the result is guaranteed to be correct when i=1 and i=2.

==================================================== ==========
The above solution is wrong, because it is uncertain whether dp[i-3] will be taken or not! The first case may lead to 0 1 1, the second case may appear 1 0 1, the combination of the two cases is 0 1 1 1 0 1.

In order to determine the situation of taking or not taking, it is necessary to use two arrays choose and ignore

The state transition equation is as follows

c h o o s e [ i ] { 0   1   1 : i g n o r e [ i − 2 ] + n u m s [ i − 1 ] + n u m s [ i ] _   0   1 : i g n o r e [ i − 1 ] + n u m s [ i ] choose[i]\left\{ \begin{aligned} &0\ 1\ 1:&ignore[i-2]+nums[i-1]+nums[i]\\ &\_\ 0\ 1:&ignore[i-1]+nums[i] \\ \end{aligned} \right. choose[i]{ 0 1 1_ 0 1ignore[i2]+nums[i1]+nums[i]ignore[i1]+nums[i]

i g n o r e [ i ] { _   1   0 : c h o o s e [ i − 1 ] _   0   0 : i g n o r e [ i − 1 ] ignore[i]\left\{ \begin{aligned} \_\ 1\ 0:&choose[i-1]\\ \_\ 0\ 0:&ignore[i-1] \\ \end{aligned} \right. ignore[i]{ _ 1 0_ 0 0choose[i1]ignore[i1]

============================================================

The above method has no problem when the data are all positive integers, but if there are negative numbers, it is easy for three consecutive households not to steal. So the transfer equation of ignore should be modified.

c h o o s e [ i ] { 0   1   1 : i g n o r e [ i − 2 ] + n u m s [ i − 1 ] + n u m s [ i ] _   0   1 : i g n o r e [ i − 1 ] + n u m s [ i ] choose[i]\left\{ \begin{aligned} &0\ 1\ 1:&ignore[i-2]+nums[i-1]+nums[i]\\ &\_\ 0\ 1:&ignore[i-1]+nums[i] \\ \end{aligned} \right. choose[i]{ 0 1 1_ 0 1ignore[i2]+nums[i1]+nums[i]ignore[i1]+nums[i]

i g n o r e [ i ] { _   1   0 : c h o o s e [ i − 1 ] 1   0   0 : c h o s s e [ i − 2 ] ignore[i]\left\{ \begin{aligned} \_\ 1\ 0:&choose[i-1]\\ 1\ 0\ 0:&chosse[i-2] \\ \end{aligned} \right. ignore[i]{ _ 1 01 0 0choose[i1]chosse[i2]

The initialization of i=0 and i=1 must follow the transfer equation! If it is out of bounds, it is directly regarded as zero.

ignore[0] = 0; ignore[1] = max(0 ,choose[0]);
choose[0] = nums[0], choose[1] = max(nums[0]+nums[1], ignore[0]+nums[1]);

Topic upgrade (Meituan 23 spring)

To upgrade the topic, you cannot steal 2 consecutive households, but there are k chances of violating this rule. What is the maximum value that can be stolen?

We only use a two-dimensional array dp, dp[k][i] means that there are k opportunities, the maximum value that can be obtained by the i-th item, we can choose the i-th item or give it up, these k opportunities are available or not .

dp [ k ] [ i ] { use the opportunity for the i-th item: dp [ k − 1 ] [ i − 1 ] + nums [ i ] do not use the opportunity for the i-th item: dp [ k ] [ i − 1 ] dp[k][i]\left\{ \begin{aligned} & the opportunity to use the i-th item: &dp[k-1][i-1]+nums[i]\\ & not to the i-th item Use opportunity: &dp[k][i-1]\\ \end{aligned} \right.dp[k][i]{ Use the opportunity for the i - th item:Opportunities are not used for the i -th item:dp[k1][i1]+nums[i]dp[k][i1]

Guess you like

Origin blog.csdn.net/weixin_43742643/article/details/129809362