你可以用DP来解决这个问题,首先设置你不买卖股票的情况,所以第一个利润为零,按照相同的顺序获利
仅进行一笔交易时
跟踪数组并保持之前价格的最小值,最大利润为数组中的最大值 - 最小值。所以问题基本上是在数组中找到最大值和最小值,差异将是最大利润,这里我们只是更新利润数组,以了解在特定日期进行交易之前的最大利润是多少。该数组将用作询问进一步事务中的数据使用情况。
// Condition for the only one transaction is possible
for (int i = 1; i < n; i++) {
min = Math.min(price[i - 1], min);
profit[i] = Math.max(profit[i - 1], price[i] - min);
}
如果最多可以进行两次交易
现在事情变得很棘手,我们必须跟踪之前为获得最大利润所做的任何计算,直到 k-1 交易(这里 k=2)。对于任意数量的事务,该问题都可以成为动态问题。
profit for a particular day is = max{ if no transaction is made (Then previous max profit, ie profit[i - 1]),
previous_profit + Max of sale possible{present price - all previous price(i,i-1,...0))
对于 k=2
// Condition for at most two transaction is possible
for (int i = 1; i < n; i++) {
max = Math.max(max, profit[i] - price[i]);
profit[i] = Math.max(profit[i - 1], max + price[i]);
}
这是 k 笔交易的通用代码
我们只需要两个数组来跟踪之前的利润值并在每次迭代中覆盖。也可以使用二维数组完成,但我们不需要任何以前的数据,所以我用偶数和正数据数组制作了它
package DynamicProblems;
public class StockSales {
private static int maxProfit(int price[], int n, int k) {
int currentProfit[] = new int[n];
int previousProfit[];
int evenProfit[] = new int[n];
int oddProfit[] = new int[n];
for (int t = 0; t <= k - 1; t++) {
int max = Integer.MIN_VALUE;
if (t % 2 == 1) {
currentProfit = oddProfit;
previousProfit = evenProfit;
} else {
currentProfit = evenProfit;
previousProfit = oddProfit;
}
for (int i = 1; i < n; i++) {
max = Math.max(max, previousProfit[i - 1] - price[i - 1]);
currentProfit[i] = Math.max(currentProfit[i - 1], max + price[i]);
}
}
return currentProfit[n - 1];
}
public static void main(String args[]) {
int price[] = {3, 4, 10, 103};
int k = 1;
int n = price.length;
System.out.println("\nMaximum Profit = " + maxProfit(price, n, k));
}
}