309. Best Time to Buy and Sell Stock with Cooldown
参考:团灭股票问题
base问题:188. Best Time to Buy and Sell Stock IV
问题:
股票问题:
给出一组一支股票每日的价格数组。prices[]
每一天的操作可以为:买buy,卖sell,不操作rest
在第二次buy之前,需要离上一次sell隔一天冷静期,求可获得的最大收益是多少。
Example: Input: [1,2,3,0,2] Output: 3 Explanation: transactions = [buy, sell, cooldown, buy, sell] |
解法:DP(动态规划)
1.确定【状态】:
- 当前的天数:第 i 天
- 当前经过的交易次数:第 k 次
- 当前的股票持有状况:p:0未持有(待买入),1 持有(待卖出)
2.确定【选择】:
- 当前p=0(未持有,待买入状态):
- 选择 1 :由本日卖出sell导致:dp[i-1][k][1]+prices[i] (昨天持股+今天卖出prices[i])
- 选择 2:本日不操作rest: dp[i-1][k][0] (昨天未持股+今天不操作)
- 当前p=1(持有,待卖出状态):
- 选择 1 :由本日买入buy导致:dp[i-2][k][0]-prices[i] (昨前天未持股+今天买入prices[i])
- 选择 2:本日不操作rest: dp[i-1][k][1] (昨天持股+今天不操作)
3. dp[i][k][p]的含义:
今天为第i天,交易k次,持有状态为p的状态下,持有的最大收益。
4. 状态转移:
dp[i][p]=
- 当前p=0(未持有,待买入状态):MAX {
- 选择 1 :由本日卖出sell导致:dp[i-1][1]+prices[i] (昨天持股+今天卖出prices[i])
- 选择 2:本日不操作rest: dp[i-1][0] (昨天未持股+今天不操作) }
- 当前p=1(持有,待卖出状态):MAX {
- 选择 1 :由本日买入buy导致:dp[i-2][0]-prices[i] (前天未持股+今天买入prices[i])
- 选择 2:本日不操作rest: dp[i-1][1] (昨天持股+今天不操作)}
5. base case:
- i==0
- dp[0][0]= 0
- dp[0][1]= -∞(不可能存在的情况,用-∞表示)
- 当i==1的时候,求dp[i][1]时,需要知道dp[i-2][0],按照dp[i][1]含义在第一天的时候
- 由本日买入buy:-princes[i] ->因此,此时相当于dp[i-2][0]=0
- 本日不操作rest:dp[0][1]
代码参考:
1 class Solution { 2 public: 3 //dp[i][k][p]: ignore k 4 //case_1: now without position: = max(sell , rest) 5 // dp[i][k][0] = max(dp[i-1][k][1]+prices[i], dp[i-1][k][0]) 6 //case_2: now with position: = max(buy , rest) 7 // dp[i][k][1] = max(dp[i-2][k-1][0]-prices[i], dp[i-1][k][1]) 8 //base case: 9 //dp[0][0] = 0; 0-th day without position 10 //dp[0][1] = -infinite; (imposible)0-th day with position 11 int maxProfit(vector<int>& prices) { 12 int n = prices.size(); 13 vector<vector<int>> dp(n+1, vector<int>(2, 0)); 14 dp[0][1] = INT_MIN; 15 for(int i=1; i<=n; i++) { 16 dp[i][0] = max(dp[i-1][1]+prices[i-1], dp[i-1][0]); 17 if(i==1) dp[i][1] = -prices[i-1]; 18 else dp[i][1] = max(dp[i-2][0]-prices[i-1], dp[i-1][1]); 19 } 20 return dp[n][0]; 21 } 22 };
♻️ 优化:
空间复杂度:2维->1维
去掉 i
需要前一次的dp[][0], dp[][1] ->dp_0, dp_1
还有前前一次的dp[][0] ->dp_0_pre
代码参考:
class Solution { public: int maxProfit(vector<int>& prices) { int n = prices.size(); int dp_0=0, dp_1=INT_MIN; int dp_0_pre=0;//if(i==1) dp[i][1] = -prices[i-1]; for(int i=1; i<=n; i++) { int tmp = dp_0; dp_0 = max(dp_1+prices[i-1], dp_0); dp_1 = max(dp_0_pre-prices[i-1], dp_1); dp_0_pre = tmp; } return dp_0; } };
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!