LeetCode——309. Best Time to Buy and Sell Stock with Cooldown(卖股票系列+冷却时间)

一、题目309:

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)

示例:

Input: [1,2,3,0,2]
Output: 3 
Explanation: transactions = [buy, sell, cooldown, buy, sell]

 

二、分析

由于是股票,所以又买也有卖,一般需要设置两个dp数组进行状态保存,由于中间有一段时间的冷却,所以也可以设置三个数组(买、卖、冷却)来进行状态存储,设置三个数组,并进行题解稍显繁琐,具体可以参见:

https://www.cnblogs.com/grandyang/p/4997417.html

https://www.cnblogs.com/jdneo/p/5228004.html

方法一:

引入辅助数组sellsbuys:

  • sells[i]表示在第i天卖出股票所能获得的最大累积收益
    buys[i]表示在第i天买入股票所能获得的最大累积收益
    初始化令sells[0] = 0,buys[0] = -prices[0]

第i天交易时获得的累计收益只与第i-1天与第i-2天有关

记第i天与第i-1天的价格差:delta = price[i] - price[i - 1]

状态转移方程为:

sells[i] = max(buys[i - 1] + prices[i], sells[i - 1] + delta) 
buys[i] = max(sells[i - 2] - prices[i], buys[i - 1] - delta)

含义为:

第i天卖出的最大累积收益 = max(第i-1天买入~第i天卖出的最大累积收益, 第i-1天卖出后反悔~改为第i天卖出的最大累积收益)
第i天买入的最大累积收益 = max(第i-2天卖出~第i天买入的最大累积收益, 第i-1天买入后反悔~改为第i天买入的最大累积收益)

最终结果为sells.back(),只有卖了才有收益。

 

方法二:

方法二由方法一拓展而来:

第i-1天卖出后反悔,改为第i天卖出 等价于 第i-1天持有股票,第i天再卖出
第i-1天买入后反悔,改为第i天买入 等价于 第i-1天没有股票,第i天再买入

所以,这里,改变辅助数组的意义:

sells[i]表示在第i天不持有股票所能获得的最大累计收益
buys[i]表示在第i天持有股票所能获得的最大累计收益

状态转移方程:

sells[i] = max(sells[i - 1], buys[i - 1] + prices[i])
buys[i] = max(buys[i - 1], sells[i - 2] - prices[i])

其中,但i<2时:buys[i] = max(buys[i - 1],  - prices[i]);

最终结果为sells.back();

代码示例如下:

class Solution {
public:
	int maxProfit(vector<int>& prices) {
		if (prices.empty())
			return 0;
		vector<int> Buy(prices.size(), 0);//表示第i天,手中持有股票
		vector<int> Sell(prices.size(), 0);  //表示第i天,手中没有股票
		Buy[0] = -prices[0];
		for (int i = 1; i < prices.size(); i++)
		{
			Sell[i] = max(Buy[i - 1] + prices[i], Sell[i - 1]);
			if (i >= 2)
				Buy[i] = max(Sell[i - 2] - prices[i], Buy[i - 1]);
			else
				Buy[i] = max(-prices[i], Buy[i - 1]);
		}
		return Sell[prices.size() - 1];
	}
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值