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:
Input: [1,2,3,0,2]
Output: 3
Explanation: transactions = [buy, sell, cooldown, buy, sell]
在某一天能否买入,还要看之前的几天状态,并且,最终目的是求最大值,而且无法确定某一天是否买入或者卖出,所以采取动态规划,之前做过的Best Time to Buy and Sell Stock I II III IV,中使用的local和global的递推式方法在此题不再适用,因为本题的要求是不限买入的次数。
现设两个数组,一个是have,have[i]表示第i天内,手中持有股票的情况下,所能具备的最大收入,另一个是lose,lose[i]表示第i天内,手中没有股票的情况下,所能具备的最大收入。
第一天,sell[0] = 0,buy[0] = -1 * prices[0]
第二天,sell[1] = 0 > (prices[1] - prices[0]) ? 0 : (prices[1] - prices[0]),buy[1] = buy[0] > (-1 * prices[1]) ? buy[0] : (-1 * prices[1])
...
第i天,sell[i],是第i天内手中没有股票的情况,那么有两种情况,第一、昨天没有股票,今天也没有股票,此时sell[i] = sell[i - 1],第二、昨天手中有股票,但是今天卖出去了,所以到最后,手中也没有股票,此时sell[i] = buy[i - 1] + prices[i],所以sell[i]取上面两种情况的最大值。
buy[i],是第i天内手中有股票的情况,那么仍然有两种情况,第一、昨天手中没有股票,今天有股票,但是此时要注意到题目中明确说明了具有一天的冷却期,也就是说,如果昨天有股票,并且在昨天卖出的话,今天是不能买的,所以如果昨天没有股票,今天手中有股票,只能说明是前天卖出了之前手中的股票,或者前天手中没有股票,并且昨天也没买,此时buy[i] = sell[i - 2] - prices[i],第二、昨天手中就有股票,今天仍有股票,说明上一次买的股票没有卖出去,所以此时buy[i] = buy[i - 1],所以buy[i]取上面两种情况的最大值。于是出现了下面的代码:
Code:
int maxProfit(vector<int>& prices)
{
int size = prices.size();
if(size == 0 || size == 1)return 0;
int * have = new int[size];
int * lose = new int[size];
have[0] = -1 * prices[0];
lose[0] = 0;
int diff = prices[1] - prices[0];
lose[1] = diff > 0 ? diff : 0;
have[1] = have[0] > (-1 * prices[1]) ? have[0] : (-1 * prices[1]);
for(int i = 2; i < size; i++)
{
int temp1 = lose[i - 1];
int temp2 = have[i - 1] + prices[i];
lose[i] = temp1 > temp2 ? temp1 : temp2;
int temp3 = lose[i - 2] - prices[i];
have[i] = have[i - 1] > temp3 ? have[i - 1] : temp3;
}
return lose[size - 1];
}