题目
题目链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-with-cooldown/description/
解法
买和卖是不同的两种状态,相互转换而来,题目要求买之前必须要卖掉之前的股票,因此必须要使用两个数组 buy 和 sell 分别表示。这两个数组是相互依赖的。
buy[i] 表示买第 i 只股票获得的最大利润,可以选择买,也可以不买。sell[i] 表示卖第 i 只股票获得的最大利润,可以选择卖,也可以不卖。
状态转移方程如下,对每种情况取max:
买 { 买: s e l l [ i − 2 ] − p r i c e [ i ] (前面的卖了才能继续买) 不买: b u y [ i − 1 ] 买\left\{ \begin{aligned} 买:&sell[i-2]-price[i] (前面的卖了才能继续买)\\ 不买:&buy[i-1] \\ \end{aligned} \right. 买{ 买:不买:sell[i−2]−price[i](前面的卖了才能继续买)buy[i−1]
卖 { 卖: b u y [ i − 1 ] + p r i c e [ i ] (卖是从买的状态转换来的) 不卖: s e l l [ i − 1 ] 卖\left\{ \begin{aligned} 卖:&buy[i-1]+price[i] (卖是从买的状态转换来的)\\ 不卖:&sell[i-1] \\ \end{aligned} \right. 卖{ 卖:不卖:buy[i−1]+price[i](卖是从买的状态转换来的)sell[i−1]
初始化。buy[0] 和 sell[0] 的初始化很简单,buy[1] 会遇到sell[-1],当作零处理,即比较前两值股票的最小值,sell[1] 则是按照转移方程处理。保证 n=2 的时候符合答案。
代码:
class Solution {
public:
int maxProfit(vector<int>& prices) {
int len = prices.size();
if (len == 1) {
return 0;
}
vector<int> buy(len, 0), sell(len, 0);
buy[0] = -prices[0];
buy[1] = max(-prices[0], -prices[1]);
sell[0] = 0;
sell[1] = max(0, -prices[0] + prices[1]);
for (int i = 2; i < len; i++) {
buy[i] = max(sell[i-2]-prices[i], buy[i-1]);
sell[i] = max(buy[i-1]+prices[i], sell[i-1]);
}
return sell[len-1];
}
};