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]

卖东西,求最大利润。限制条件有:

1、卖了上一次的东西后,才能买下一次的。(一次交易完成以后才能开启下一次交易)。

2、卖掉东西的第二天,什么也不能干。

解决:对于每天,有三种选择:1、买;2、卖;3、冷却。

创建数组 vector<vector<int>> dp(3, vector<int>(len)); 

// dp[0]: buy
// dp[1]: sell
// dp[2]: cooldown

那么有递推公式

dp[0][i] = max(dp[2][i-1] - prices[i], dp[0][i-1]);
dp[1][i] = dp[0][i-1] + prices[i];
dp[2][i] = max( dp[0][i-1], max(dp[1][i-1], dp[2][i-1]) );

解释:

如果第i+1天的库存状态是买进,则利润构成有两种情况:1、前一天冷却;2、前一天的状态也是买进。两者之间选择利润较大的值。(选择一个最低的买入价格)。

如果第i+1天的库存状态是卖出,则利润构成只有一种情况,就是前一天的库存状态是买进。

如果第i+1天的库存状态是冷却,利润就是前一天三种情况的最大值。

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

 

posted @ 2017-12-29 21:33  Zzz...y  阅读(199)  评论(0编辑  收藏  举报