题目大意:给出股票价格数组,可以进行多次买卖,但是卖出的第二天要休息,求最大收益
分析:动态规划。
状态:以下处于冷冻期是指第i天卖出了股票,导致第i+1天处于冷冻期,无法买入
dp[i][0]:第i天持有股票的最大收益
dp[i][1]:第i天不持有股票,且处于冷冻期的最大收益
dp[i][2]:第i天不持有股票,且不处于冷冻期的最大收益
初始化:dp[0][0]=-prices[0]
结果:max(dp[n - 1][1],dp[n-1][2])
状态转移方程:
dp[i][0] = max(dp[i-1][0],dp[i-1][2]-prices[i]) //要么前一天就持有股票;要么前一天不持有且不冷冻,今天买入
dp[i][1] = dp[i-1][0]+prices[i] //今天卖出导致冷冻期,所以前一天必须持有股票
dp[i][2] = max(dp[i-1][1],dp[i-1][2]) //今天没有买入卖出操作,所以前一天必须不持有股票,可冷冻可不冷冻
空间优化:第i天的状态只和前一天有关,所以可以用三个变量以O(1)的空间复杂度完成。
代码:
class Solution {
public:
int maxProfit(vector<int>& prices) {
if (prices.empty()) {
return 0;
}
int n = prices.size();
// f[i][0]: 手上持有股票的最大收益
// f[i][1]: 手上不持有股票,并且处于冷冻期中的累计最大收益
// f[i][2]: 手上不持有股票,并且不在冷冻期中的累计最大收益
vector<vector<int>> f(n, vector<int>(3));
f[0][0] = -prices[0];
for (int i = 1; i < n; ++i) {
f[i][0] = max(f[i - 1][0], f[i - 1][2] - prices[i]);
f[i][1] = f[i - 1][0] + prices[i];
f[i][2] = max(f[i - 1][1], f[i - 1][2]);
}
return max(f[n - 1][1], f[n - 1][2]);
}
};
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/solution/zui-jia-mai-mai-gu-piao-shi-ji-han-leng-dong-qi-4/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
空间优化:
class Solution {
public:
int maxProfit(vector<int>& prices) {
if (prices.empty()) {
return 0;
}
int n = prices.size();
int f0 = -prices[0];
int f1 = 0;
int f2 = 0;
for (int i = 1; i < n; ++i) {
int newf0 = max(f0, f2 - prices[i]);
int newf1 = f0 + prices[i];
int newf2 = max(f1, f2);
f0 = newf0;
f1 = newf1;
f2 = newf2;
}
return max(f1, f2);
}
};
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/solution/zui-jia-mai-mai-gu-piao-shi-ji-han-leng-dong-qi-4/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。