(动态规划,状态机) leetcode 股票问题

 

https://leetcode.com/problems/best-time-to-buy-and-sell-stock/

思路参考链接:

https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/solution/yi-ge-fang-fa-tuan-mie-6-dao-gu-piao-wen-ti-by-lab/

个问题的「状态」有三个,第一个是天数,第二个是允许交易的最大次数,第三个是当前的持有状态(即之前说的 rest 的状态,我们不妨用 1 表示持有,0 表示没有持有)。然后我们用一个三维数组就可以装下这几种状态的全部组合:

复制代码
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int dp_i_0 = 0, dp_i_1 = INT_MIN;   //base case
        for(int i=0; i<prices.size(); ++i){
            dp_i_0 = max(dp_i_0, dp_i_1+prices[i]);
            dp_i_1 = max(dp_i_1, -prices[i]);
        }
        return dp_i_0;
    }
};
复制代码

 

https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/

复制代码
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int dp_i_0 = 0, dp_i_1 = INT_MIN;
        for(int i=0; i<prices.size(); ++i){
            int temp = dp_i_0;
            dp_i_0 = max(dp_i_0, dp_i_1 + prices[i]);
            dp_i_1 = max(dp_i_1, temp-prices[i]);
        }
        return dp_i_0;
    }
};
复制代码

 

https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/

含冷冻期(cooldown) 一天的意思是在卖出股票后,要rest一天后,才能买入。

复制代码
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int dp_i_0 = 0, dp_i_1 = INT_MIN;
        int dp_pre_0 = 0;   //dp[i-2][0]
        for(int i=0; i<prices.size(); ++i){
            int temp = dp_i_0;
            dp_i_0 = max(dp_i_0, dp_i_1+prices[i]);
            dp_i_1 = max(dp_i_1, dp_pre_0 - prices[i]);  //第i天持有股票,只能在i-2天及以前买进
            dp_pre_0 = temp;
        }
        return dp_i_0;
    }
};
复制代码

 

复制代码
class Solution {
public:
    int maxProfit(vector<int>& prices, int fee) {
        int dp_i_0 = 0, dp_i_1 = INT_MIN;
        for(int i=0; i<prices.size(); ++i){
            int temp = dp_i_0;
            dp_i_0 = max(dp_i_0, dp_i_1+prices[i]);
            dp_i_1 = max(dp_i_1, temp-prices[i]-fee);
        }
        return dp_i_0;
    }
};
复制代码

 

 

 

 

复制代码
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int dp_i_1_0 = 0, dp_i_1_1 = INT_MIN;
        int dp_i_2_0 = 0, dp_i_2_1 = INT_MIN;
        for(int price: prices){
            dp_i_2_0 = max(dp_i_2_0, dp_i_2_1 + price);
            dp_i_2_1 = max(dp_i_2_1, dp_i_1_0 - price);
            dp_i_1_0 = max(dp_i_1_0, dp_i_1_1 + price);
            dp_i_1_1 = max(dp_i_1_1, - price);
        }
        return dp_i_2_0;
    }
};
复制代码

 

复制代码
class Solution {
public:
    int maxProfit(int k, vector<int>& prices) {
        int n = prices.size();
        if(k > n/2)
            return maxprofit(prices);
        
        vector<int> sold(k+1, 0), bought(k+1, INT_MIN);
        for(int price: prices){
            for(int i = 1; i<=k; ++i){
                sold[i] = max(sold[i], bought[i] + price);   //sold[i]指当前操作为卖出,即不持有股h
                bought[i] = max(bought[i], sold[i-1] - price);  //bought[i]指当前操作为买进,即持有股票

            }
        }
        return sold[k];
    }
    
    int maxprofit(vector<int>& prices){
        //k = +infinity
        int dp_i_0 = 0, dp_i_1 = INT_MIN;
        for(int p : prices){
            int temp = dp_i_0;
            dp_i_0 = max(dp_i_0, dp_i_1 + p);
            dp_i_1 = max(dp_i_1, temp - p);
        }
        return dp_i_0;
    }
};