【LeetCode】Dynamic programming training (4)

Interview question 17.16. Masseur (robbing house|)

Click to view: masseuse


A well-known masseuse will receive a steady stream of appointment requests, and each appointment can be chosen or not accepted. There is a break between each service appointment, so she cannot accept adjacent appointments. Given a sequence of appointment requests, find the optimal appointment set (the longest total appointment time) for the masseur, and return the total number of minutes.

Example 1:
Input: [1,2,3,1]
Output: 4
Explanation: Select appointment 1 and appointment 3, total duration = 1 + 3 = 4.
Example 2:
Input: [2,7,9,3,1]
Output: 12
Explanation: Select appointment 1, appointment 3 and appointment 5, total duration = 2 + 9 + 1 = 12.


topic analysis

Starting from the first number 1, adjacent numbers cannot be put together, so choose 3 again
, that is, 1+3 = 4.
Starting from the second number 2, adjacent numbers cannot be put together, so choose 1 again
That is, 2+1 = 3,
so 4 is the longest appointment time

state transition equation

In the above analysis process, it was found that from left to right

dp[i] : Indicates the longest appointment time when position i is selected


There are two cases for the i position:

1. Select the value of position i, and use f to represent
f[i]: when selecting position i, the value of position i (nums[i]) must be selected, and the longest appointment time at this time

2. Do not select the value of position i, and do not select g to indicate
g[i]: when position i is selected, the value of position i (nums[i]) is not selected, and the longest appointment time at this time


f[i] means position i must be selected, then position i-1 must not be selected
because the longest appointment time is required, so look for the longest appointment time in the interval [0, i-1], and position i-1 It cannot be obtained, that is, g[i-1]
plus the value of i position is the longest reservation time in the interval [0,i]

The state transition equation is:
f[i] = g[i-1]+nums[i]


g[i] means that position i must not be selected, and position i-1 is divided into two cases.
In the first case, position i-1 is selected
because the longest reservation time is required, so look for [0, i-1] The longest appointment time in the interval, and the i-1 position can be taken, that is, f[i-1]
The longest appointment time in the first case is: g[i]=f[i-1]

In the second case, the i-1 position is not selected
because the longest appointment time is required, so look for the longest appointment time in the [0, i-1] interval, and the i-1 position cannot be taken, that is, g[ i-1]
The longest appointment time in the second case is: g[i]=g[i-1]

The state transition equation is:
g[i] =max(f[i-1],g[i-1]);


full code

class Solution {
    
    
public:
    int massage(vector<int>& nums) {
    
    
       int n=nums.size();

       //处理边界条件
       if(n==0)
       {
    
    
           return 0;
       }
       vector<int>f(n,0);
       vector<int>g(n,0);
       int i=0;

       //为了防止越界问题 g[0]和f[0]都需要提前赋值
       g[0]=0;
       f[0]=nums[0];
       for(i=1;i<n;i++)
       {
    
    
          f[i]=g[i-1]+nums[i];
          g[i]=max(f[i-1],g[i-1]);
       }
       //返回 取到最后一个位置和 不取最后一个位置 两者的最大值
       return max(f[n-1],g[n-1]);
    }
};

i starts from 1, so to initialize f[0] and g[0]
f[0] contains the value of nums[0], so the first element of nums
g[0] does not contain the value of nums[0] , so it is 0

The return value is the maximum value between selecting the last position and not selecting the last position

213. Dajia Palace II

Click to view: House Robbery II


You are a professional thief planning to rob houses along the street, each of which has a certain amount of cash hidden in it. All the houses in this place are arranged in a circle, which means that the first house and the last house are right next to each other. At the same time, adjacent houses are equipped with interconnected anti-theft systems. If two adjacent houses are broken into by thieves at the same night, the system will automatically call the police.
Given an array of non-negative integers representing the amount stored in each house, calculate the maximum amount you can steal tonight without triggering the alarm.

Example 1:
Input: nums = [2,3,2]
Output: 3
Explanation: You cannot first steal house 1 (amount = 2) and then steal house 3 (amount = 2), because they are adjacent.
Example 2:
Input: nums = [1,2,3,1]
Output: 4
Explanation: You can first steal house #1 (amount = 1) and then steal house #3 (amount = 3).
Maximum amount stolen = 1 + 3 = 4.

topic analysis

Equivalent to robbing houses | The difference is that the ends are connected

If you take the value 2 in the first node, you cannot take the value 2 in the third node, because the ends are connected, so the amount that can be stolen at this time is 2

If the value 3 in the second node is taken, the amount that can be stolen is 3,
so the maximum amount stolen is 3

Through classification discussions, the circular problem is converted into two linear robbing|


Case 1:

If you steal the position with the subscript 0, because it is connected end to end, the position with the subscript 1 and the position with the subscript n-1 cannot be stolen, and you can steal it randomly within the [2,n-2] interval
( using the dynamic transfer equation)


Case two:

If you do not steal the position with subscript 0, you can steal it at will in the interval [1,n-1] at this time (using the dynamic transfer equation)

Take the maximum value of the two cases as the maximum amount

state transition equation

This dynamic transfer equation is used in the case of the above analysis in the [2, n-2] interval in case 1 to steal randomly and in case 2 in the [1, n-1] interval can be stolen at will


f[i]: means stealing nums[i] when stealing to position i, the maximum amount at this time
g[i]: indicating not stealing nums[i] when stealing to position i, the maximum amount at this time


If the i position is stolen to the value of nums[i], if you want to ask for the maximum amount of [0,i], you must first ask for the maximum amount of [0,i-1] and since the adjacent positions cannot be stolen,
so The i-1 position cannot be stolen, that is, the value of g[i-1]
plus nums[i] is the maximum amount in the interval [0,i]

The state transition equation is:
f[i]=g[i-1]+nums[i]


If the i position is not stolen to the value of nums[i], the i-1 position is divided into two cases:

Situation 1:
If the value of position i-1 is stolen,
because the maximum amount is required, so look for the longest amount in the interval [0, i-1], and position i-1 can be obtained, that is, f[i -1]
The maximum amount in the first case is: g[i]=f[i-1]

Situation 2:
If the value of position i-1 is not stolen,
because the maximum amount is required, so look for the maximum amount in the interval [0, i-1], and position i-1 cannot be obtained, that is, g[ i-1]
The longest maximum amount in the second case is: g[i]=g[i-1]

The state transition equation is:
g[i]=max(f[i-1],g[i-1]);

full code

class Solution {
    
    
public:
    int rob1(vector<int> &nums,int left,int right)
    {
    
    
        //区间不存在
        if(left>right)
        {
    
    
            return 0;
        }
        int n=nums.size();
        vector<int>f(n,0);
        vector<int>g(n,0);
        int i=0;
        //为了防止越界问题,所以下标left处要提前赋值
        f[left]=nums[left];
        g[left]=0;
        for(i=left;i<=right;i++)
        {
    
    
            f[i]=g[i-1]+nums[i];
            g[i]=max(f[i-1],g[i-1]);
        }
        //求 取到最后一个位置 和 没有取到最后一个位置 两者的最大值
        return max(f[right],g[right]);
    }
    int rob(vector<int>& nums) {
    
    
        int n=nums.size();
        //第一个位置取到值 和 第一个位置没有取到值 的两种情况
       return max(nums[0]+rob1(nums,2,n-2),rob1(nums,1,n-1));
    }
};

The value of n is 1 to 100. If n is 1, n-2 is -1, which will cause the subscript left(1) to be smaller than the subscript right(2), and the interval does not exist

To call rob1, just steal randomly in the interval [left, right], which is equivalent to robbing the house | the code is calling

740. Delete and get points

Click to view: delete and get points


You are given an array of integers nums on which you can perform some operations.
In each operation, select any one of nums[i], delete it and get the points of nums[i]. Afterwards, you have to remove all elements equal to nums[i] - 1 and nums[i] + 1.
You start with 0 points. Returns the maximum number of points you can gain through these operations.

Example 1:
Input: nums = [3,4,2]
Output: 6
Explanation:
Deleting 4 gets 4 points, so 3 is also deleted.
Afterwards, remove 2 for 2 points. Get 6 points in total.
Example 2:
Input: nums = [2,2,3,3,3,4]
Output: 9
Explanation:
Delete 3 to get 3 points, then delete two 2 and 4.
After that, remove 3 again to get 3 points, and remove 3 again to get 3 points.
A total of 9 points are awarded.

topic analysis

insert image description here
Delete a 3 and get 3 points. At the same time, all 2 and 4 are also deleted. Delete 3 in turn and get the corresponding points.
Get 9 points in total

preprocessing

If the stored numbers are all continuous, it is equivalent to the house robbery problem (two adjacent numbers cannot be selected).
For example: if you choose 1, you cannot choose 2


But like this kind of discontinuous number, lack of numbers 3 and 5 6, there is no way to use a solution similar to the problem of robbing houses


Use the subscript to represent the corresponding number, such as: the subscript is 1, and the number arr[i] represented as 1 : represents the number i, and the subscripts of
the sum that appear at this time are continuous, so you can use the solution to the problem of house robbery For example: if you select the number with the subscript 1, you cannot select the number with the subscript 2, you can only choose the number with the subscript 3 or the number with the subscript 4

Count the number in the original array into the arr array, and rob the house in the arr array

state transition equation

The following is the state transition equation of the house robbery problem (that is, the original array is changed to the arr array, and the others are the same)


There are two situations for position i:
1. Select the value of position i, choose f to represent
f[i]: When selecting position i, the value of position i (arr[i]) must be selected, and the maximum number of points at this time

2. Do not select the value of position i, and do not select g to indicate
g[i]: means that when position i is selected, the value of position i (arr[i]) is not selected, and the maximum number of points at this time


f[i] means that position i must be selected, and position i-1 must not be selected
because the maximum number of points is required, so look for the maximum number of points in the interval [0, i-1], and position i-1 cannot be selected To that is, g[i-1]
plus the value of the i position is the maximum number of points in the [0,i] interval

The state transition equation is:
f[i] = g[i-1]+arr[i]


g[i] means that position i must not be selected, and position i-1 is divided into two cases.
In the first case, position i-1 is selected
because the maximum number of points is required, so look for the interval [0, i-1] The maximum number of points, and the i-1 position can be taken, that is,
the maximum number of points in the first case of f[i-1] is: g[i]=f[i-1]

In the second case, the i-1 position is not selected
because the maximum number of points is required, so look for the maximum number of points in the interval [0, i-1], and the i-1 position cannot be taken, that is, g[i-1]
The maximum number of points in the second case is: g[i]=g[i-1]

The state transition equation is:
g[i] =max(f[i-1],g[i-1]);

full code

class Solution {
    
    
public:
    int deleteAndEarn(vector<int>& nums) {
    
    
         int i=0;
         int maxsize=0;
         //因为arr数组下标最大值为原数组的最大值 所以寻找原数组的最大值
         for(i=0;i<nums.size();i++)
         {
    
    
            if(nums[i]>maxsize)
            {
    
    
                maxsize=nums[i];
            }
         }
         //通过原数组的最大值创建arr数组大小
         vector<int>arr(maxsize+1,0);
         for(i=0;i<nums.size();i++)
         {
    
    
             //arr[i]代表 i这个数的总和
             arr[nums[i]]+=nums[i];
         }
         //下面进行 打家劫舍问题
        int n=arr.size();
        //[i]f代表取arr[i]这个位置的时候,能够得到的最大点数
        //g[i]代表不能取arr[i]这个位置的时候,能够得到的最大点数
         vector<int>g(n,0);
         vector<int>f(n,0);
         //为了避免越界 将g[0] f[0]进行初始化
         g[0]=0;
         f[0]=arr[0];
         for(i=1;i<n;i++)
         {
    
    
             //状态转移方程
             f[i]=g[i-1]+arr[i];
             g[i]=max(g[i-1],f[i-1]);
         }
         //返回 取到最后一个位置 和 不取最后一个位置 两者中的最大值
         return max(f[n-1],g[n-1]);
    }
};

Supongo que te gusta

Origin blog.csdn.net/qq_62939852/article/details/131393853
Recomendado
Clasificación