# 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]; } }