# 188. The best time to buy and sell stocks IV

Keywords: Algorithm Dynamic Programming

# 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

## 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