状态机建模#
在 188.买卖股票的最佳时机 IV中,我们只有两个大类:买(持有)和卖(不持有)。
但在这一题中,由于冷冻期的存在,“不持有”被分成了两种完全不同的情况:
- 状态 0:持有股票
- 状态 1:刚刚卖出,处于冷冻期
- 特点:这个状态是卖出动作激发的,下一天强制不能买。
- 状态 2:不持有股票,且不在冷冻期
- 特点:这个状态意味着你已经休息够了,随时可以买入。
状态转移方程#
设 为第 天结束时,处于状态 的最大利润。
状态 0:今天结束后我“手里有货”
- 昨天就有货,今天歇着:
- 昨天没货且不在冷冻期(状态 2),今天刚买入:
- 方程:
状态 1:今天结束后我“刚刚卖出”
- 唯一来源:昨天我手里有货(状态 0),今天我把它卖了:
- 方程:
状态 2:今天结束后我“两手空空且能买”
- 昨天就是这个状态,今天继续歇着:
- 昨天我是刚卖完的冷冻期(状态 1),今天冷冻期解除了:
- 方程:
Question:「刚刚卖出」和「处于冷冻期」不应该是两种状态吗?即昨天刚刚卖出,今天处于冷冻期
这里对状态的定义为:第 天结束后所处的状态,而不是所谓的“第 天所处的状态”。
代码实现#
我们可以发现,第 天的状态只取决于第 天,因此可以直接用三个变量来维护。
public int maxProfit(int[] prices) {
int hold = -prices[0]; // 状态0
int sold = 0; // 状态1
int rest = 0; // 状态2
for (int i = 1; i < prices.length; ++i) {
int nextHold = Math.max(hold, rest - prices[i]);
int nextSold = hold + prices[i];
int nextRest = Math.max(rest, sold);
hold = nextHold;
sold = nextSold;
rest = nextRest;
}
// 最大利润一定处于“手里没货”的状态
return Math.max(sold, rest);
}java