188. The best time to buy and sell stocks IV

Keywords: Algorithm Dynamic Programming

catalogue

188. The best time to buy and sell stocks IV

subject

Given an array of integers   prices, its i-th element   prices[i] is the price of a given stock on day I.

Design an algorithm to calculate the maximum profit you can make. You can complete up to k transactions.

Note: you cannot participate in multiple transactions at the same time (you must sell the previous shares before buying again).

Example 1:

Input: k = 2, prices = [2,4,1]
Output: 2
 Explanation: on day 1 (Stock price = 2) Buy on the second day (Stock price = 4) When sold, the exchange can make a profit = 4-2 = 2 . 

Example 2:

Input: k = 2, prices = [3,2,6,5,0,3]
Output: 7
 Explanation: on day 2 (Stock price = 2) Buy on day 3 (Stock price = 6) Sell at, The exchange is profitable = 6-2 = 4 . 
     Then, on day 5 (Stock price = 0) Buy on day 6 (Stock price = 3) Sell at, The exchange is profitable = 3-0 = 3 . 

Tips:

0 <= k <= 100
0 <= prices.length <= 1000
0 <= prices[i] <= 1000

Source: LeetCode
Link: https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iv
The copyright belongs to Lingkou network. For commercial reprint, please contact the official authorization, and for non-commercial reprint, please indicate the source.

Problem solution

The question only asks the maximum profit, not the specific day to buy and sell these days. Therefore, we can consider using the method of dynamic programming.

  • Dynamic programming is used to solve multi-stage decision-making problems;
  • The question method of dynamic programming: only the optimal solution, not the specific solution;

This question can be used 123 see the problem solution with strong universality and good understanding

1. Determine the meaning of dp array and its subscript

Here, K transactions are uncertain and need to be determined by input, so it must be expressed in the state. Suppose a purchase is the beginning of a transaction.
There are two states: holding and not holding.

dp[i][k][0]: indicates the maximum profit on the i-th day when there are k transactions at most and no holding status
dp[i][k][1]: refers to the maximum profit in the holding state on the I-day, with a maximum of K transactions

2.dp array recursion

What is the state transition formula?

Assume that day i is holding

  • If no buying operation is performed on day I, dp[i][k][1] = dp[i-1][k][1]
  • If the buy operation is performed on day I, dp[i][k][1] = dp[i-1][k-1][0] - prices[i]
    dp[i][k][1] = Math.max(dp[i-1][k][1],dp[i-1][k-1][0] - prices[i])

Assume that day i is not held

  • If there is no sale on day I, then dp[i][k][0] = dp[i-1][k][0]
  • If selling is performed on day I, dp[i][k][0] = dp[i-1][k][1] + prices[i]

dp[i][k][0] = Math.max(dp[i-1][k][0],dp[i-1][k][1] + prices[i])

3.dp array initialization

When i=0, no matter how many times i can trade at most, i can only trade once when i is equal to 0. dp[0][2][1] = -prices[0] can be understood as that when i trade at most 2 times, i actually only trade once, so as long as i hold, it should be initialized to - prices[0]

dp[0][1][1] = -prices[0]
dp[0][2][1] = -prices[0]

4. Loop traversal sequence

First traverse i from small to large, and then traverse k from small to large

for(int m=1;m<=k;m++){
	dp[0][m][1] = -prices[0];
}

for(int i=1;i<prices.length;i++){
	for(int j=1;j<=k;j++){
		dp[i][j][0]  = Math.max(dp[i-1][j][0],dp[i-1][j][1] + prices[i]);
		dp[i][j][1]  = Math.max(dp[i-1][j][1],dp[i-1][j-1][0] - prices[i]);
	}
}
return dp[prices.length-1][k][0];

Scroll array

The state of i is only related to the state of i-1. You can use the rolling array to reduce the dimension, but it should be noted that dp[k][0] must precede dp[k][1], because dp[k][0] needs to use the previous dp[k][1]

for(int m=1;m<=k;m++){
	dp[m][1] = -prices[0];
}
for(int i=1;i<prices.length;i++){
	for(int j=1;j<=k;j++){
		dp[j][0]  = Math.max(dp[j][0],dp[j][1] + prices[i]);
		dp[j][1] =  Math.max(dp[j][1],dp[j-1][0] - prices[i]);
	}
}
return dp[k][0];

Optimization: because a transaction involves buying and selling for two days, if the value of k is greater than half of the array length, k will directly take half of the array length, because the number of redundant transactions cannot be reached

code

class Solution {
    public int maxProfit(int k, int[] prices) {
        int len = prices.length;
        if(k==0||len<=1) return 0;
		k=Math.min(k , prices.length/2);
             int dp [] [] = new int[k+1][2];
             for(int m=1;m<=k;m++){
	              dp[m][1] = -prices[0];
              }
             for(int i=1;i<prices.length;i++){
	            for(int j=1;j<=k;j++){
		            dp[j][0]  = Math.max(dp[j][0],dp[j][1] + prices[i]);
		            dp[j][1] =  Math.max(dp[j][1],dp[j-1][0] - prices[i]);
	    }
        }
        return dp[k][0];
        }
}

Posted by valtido on Sat, 30 Oct 2021 21:47:05 -0700