# 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]: indicates the maximum profit on the i-th day when there are k transactions at most and no holding status
dp[i][k]: 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] = dp[i-1][k]
• If the buy operation is performed on day I, dp[i][k] = dp[i-1][k-1] - prices[i]
dp[i][k] = Math.max(dp[i-1][k]，dp[i-1][k-1] - prices[i])

Assume that day i is not held

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

dp[i][k] = Math.max(dp[i-1][k]，dp[i-1][k] + 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 = -prices 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

dp = -prices
dp = -prices

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[m] = -prices;
}

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

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] must precede dp[k], because dp[k] needs to use the previous dp[k]

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

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];
for(int m=1;m<=k;m++){
dp[m] = -prices;
}
for(int i=1;i<prices.length;i++){
for(int j=1;j<=k;j++){
dp[j]  = Math.max(dp[j],dp[j] + prices[i]);
dp[j] =  Math.max(dp[j],dp[j-1] - prices[i]);
}
}
return dp[k];
}
}
```

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