# [difficult] best stock trading opportunity

Keywords: Algorithm Dynamic Programming

#### problem

Given an array arr of length N, its ith element 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.
You cannot participate in multiple transactions at the same time (you must sell the previous shares before buying again).

#### [dynamic planning ideas]

First, when k > = n / 2, this question can be the same as you can complete any transaction. The idea at this time is to grasp all growth ranges, that is, the demand.

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-fft4dfny-1631929396635) (EV) ernotecid://F1227914-1506-468F-92ED-DE7A9295E764/appyinxiangcom/27255310/ENResource/p281 )]

As shown in the figure, we can seize every opportunity to buy and sell, which is the optimal solution.
Then when k < n / 2, we need to discuss and dynamic programming.
A very easy idea, one sample as a row and one sample as a column model
At this time, for dp[i][j] day I, the maximum profit can be obtained by conducting J transactions.
In this sense, we try to deduce the dynamic transfer equation.

It is discussed by case. For dp[i][j] two cases
(1) Do not participate in selling on day i
(2) Participate in selling on day i
Result = max (case 1, case 2);
Case 1 is simply equivalent to dp[i-1][j]
Case 2: in this case, we may need to perform an enumeration and

```dp[i][j] = MAX(
dp[i][j-1] + arr[i] - arr[i],
dp[i-1][j-1] + arr[i] - arr[i-1],
dp[i-2][j-1] + arr[i] - arr[i-2],
......
dp[j-1] + arr[i] - arr
)
```

It seems that this is feasible. Its semantics is the maximum value of 0-i not sold before and sold at this time.
At this time, the most time-consuming is the enumeration behavior of [case 2]. Let's think about whether there are methods to optimize this enumeration behavior.
Look dp[i-1][j]:

```dp[i-1][j] = MAX(
dp[i-1][j-1] + arr[i-1] - arr[i-1],
dp[i-2][j-1] + arr[i-1] - arr[i-2],
dp[i-3][j-1] + arr[i-1] - arr[i-3],
......
dp[j-1] + arr[i] - arr
)
```

We extract the formula as follows:

```dp[i][j] = MAX(
dp[i][j-1]  - arr[i],
dp[i-1][j-1] - arr[i-1],
dp[i-2][j-1]  - arr[i-2],
......
dp[j-1]  - arr
) + arr[i]

dp[i-1][j] = MAX(
dp[i-1][j-1] - arr[i-1],
dp[i-2][j-1] - arr[i-2],
dp[i-3][j-1] - arr[i-3],
......
dp[j-1] - arr
) + arr[i-1]
```

At this time, the enumeration calculation of [case 2] max is the maximum value of dp[i-1][j] case 2 that can rely on the previous optimal solution, so dp[i][j] can rely on this value and omit enumeration
Namely:

```dp[i][j]= MAX(dp[i-1][j]Case 2 max ,dp[i][j-1] - arr[i]) + arr[i]
```

ok theory exists and put into practice

#### Problem solution

```package algorithmic.total.solution.common;

/**
* @program: algorithmic-total-solution
* @description: The best time to buy and sell stocks
* Given an array arr of length N, its ith element 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.
* You cannot participate in multiple transactions at the same time (you must sell the previous shares before buying again).
* @author: wangzibin
**/
public class Question4 {

public static void main(String[] args) {
int[] price=new int[]{9,3,4,9,5,1};
System.out.println(getMaxProfit(price,2));
}

public static int getMaxProfit(int[] arr, int k) {
if (arr == null || arr.length < 1) {
return 0;
}
int length = arr.length;
if (k >= length / 2) {
return getMaxProfit(arr);
} else {
int[][] dp = new int[length][k + 1];

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

private static int getMaxProfit(int[] arr) {
if (arr == null || arr.length < 1) {
return 0;
}
int sum = 0;
for (int i = 0; i < arr.length; i++) {