给定一个整数数组,其中第 i 个元素代表了第 i 天的股票价格 。
设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):
你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。
示例:
输入: [1,2,3,0,2]
输出: 3
解释: 对应的交易状态为: [买入, 卖出, 冷冻期, 买入, 卖出]
//动态规划
public int maxProfit(int[] prices) {
int n = prices.length;
if (n == 0 || n == 1) {
return 0;
}
//mem[i]表示在[i,n-1]内买卖股票的最大利润
int[] mem = new int[n];
mem[n - 1] = 0;
mem[n - 2] = prices[n - 2] < prices[n - 1] ? prices[n - 1] - prices[n - 2] : 0;
//mem2[i]表示在第i天买入股票到最后一天的最大利润
Integer[] mem2 = new Integer[n];
mem2[n - 1] = -prices[n - 1];
mem2[n - 2] = prices[n - 1] - prices[n - 2];
for (int i = n - 3; i >= 0; i--) {
int res = 0;
for (int j = i; j <= n - 2; j++) {
//在第j天买入股票
if (mem2[j] != null) {
res = Math.max(res, mem2[j]);
} else {
int res2 = Integer.MIN_VALUE;
for (int k = j + 1; k <= n - 1; k++) {
//在第k天卖出股票
int value = -prices[j] + prices[k] + (k + 2 < n ? mem[k + 2] : 0);
res = Math.max(res, value);
res2 = Math.max(res2, value);
}
mem2[j] = res2;
}
}
mem[i] = res;
}
return mem[0];
}
//动态规划2
public int maxProfit2(int[] prices) {
int n = prices.length;
if (n == 0 || n == 1) {
return 0;
}
//记录第i个操作之前 最后一个操作是买、卖还是冷冻期
int[] buy = new int[n];
int[] sell = new int[n];
int[] cold = new int[n];
buy[0] = -prices[0];
for (int i = 1; i < n; i++) {
sell[i] = Math.max(sell[i - 1], buy[i - 1] + prices[i]);
buy[i] = Math.max(buy[i - 1], cold[i - 1] - prices[i]);
cold[i] = Math.max(cold[i-1],sell[i-1]);
}
return Math.max(sell[n - 1], cold[n - 1]);
}