309. Best Time to Buy and Sell Stock with Cooldown

Say you have an array for which the ith element is the price of a given stock on day i.

Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times) with the following restrictions:

  • You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
  • After you sell your stock, you cannot buy stock on next day. (ie, cooldown 1 day)

Example:

prices = [1, 2, 3, 0, 2]
maxProfit = 3
transactions = [buy, sell, cooldown, buy, sell]

Credits:
Special thanks to @dietpepsi for adding this problem and creating all test cases.

理解题意:

可以任意次买进卖出,但是卖出之后的一天要休息才能买进。而且题目的意思:不能连续的持多股,就是说在买下一股之前把当前股卖掉

动态规划的题目关键找到代表状态的变量。这个变量与坐标有关

首先区别下面动态规划的矩阵的含义:

每天的操作有买进、卖出和休息三种状态。

下面的数组表示的是今天的持股状态。buy表示今天是持股的,sell表示今天没有持股。

buy[i]表示第i天是买进的状态,意思是,这一天是持股的。并不是说今天一定是买进操作。可能之前也已经买过了(还砸在手里没卖出去),也有可能昨天没持股,今天买的。第一种情况,buy[i]=buy[i-1],就是说今天没有做什么操作;第二种情况,今天买进了一股,受益要剪掉今天的股票价格。这个收益对应的是昨天是卖出的状态。但是由于如果昨天做了售出操作,今天是不能买的。所以要看前天的收益。代指而来的问题是,如果昨天不持股状态是延续前天的,这个sell[i-1]是可取的。怎么办?

因为这种情况下,sell[i-1]==sell[i-2]。所以buy[i]=max(buy[i-1],sell[i-2]-prices[i]) 是通用的 

sell[i]表示今天是没持股的状态。可能是今天把股票卖了,也可能之前就卖了,一直没买。

sell[i]=max(sell[i-1],buy[i-1]+prices[i]) 分别表示,今天不卖股票和卖股票的情况。

初始边界:sell[0]=0,第一天是不持股状态的收益为0,buy[0]=-prices[0] 第一天的持股状态收益为负数。

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int n=prices.size();
        if(n==0) return 0;
        vector<int> buy(n,0);
        vector<int> sell(n,0);
        buy[0]=-prices[0];
        for(int i=1;i<n;i++)
        {
            sell[i]=max(sell[i-1],buy[i-1]+prices[i]);
            if(i>1) buy[i]=max(sell[i-2]-prices[i],buy[i-1]);
            else
                buy[i]=max(buy[i-1],sell[i-1]-prices[i]);
        }
        return max(sell[n-1],buy[n-1]);
    }
};




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值