【动态规划】 状态转换

309. 最佳买卖股票时机含冷冻期

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int p_len = prices.size();
        int dp[p_len][3];
        memset(dp, 0 ,sizeof(dp));
        dp[0][0] = 0;
        dp[0][1] = 0;
        dp[0][2] = 0;
        for(int i=1;i<p_len;++i){
            int rise = prices[i] - prices[i-1];
            dp[i][0] = max(dp[i-1][0] + rise, dp[i-1][2]);
            dp[i][1] = dp[i-1][0] + rise;
            dp[i][2] = max(dp[i-1][1], dp[i-1][2]); 
            // cout << i << " " << dp[i][0] << " " << dp[i][1] << " " << dp[i][2] << endl;
        }
        return max(dp[p_len-1][1], dp[p_len-1][2]);
    }
};
//  无空间优化
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int len = prices.size();
        int dp1[len][2];
        int dp2[len][2];
        dp1[0][0] = -prices[0];
        dp1[0][1] = 0; 
        dp2[0][0] = -prices[0];
        dp2[0][1] = 0;
        for(int i=1;i<len;++i){
            dp1[i][0] = max(dp1[i-1][0], -prices[i]);
            dp1[i][1] = max(dp1[i-1][1], dp1[i-1][0] + prices[i]);
            dp2[i][0] = max(dp1[i-1][1] - prices[i], max(dp2[i-1][0], -prices[i]));
            dp2[i][1] = max(dp2[i-1][1], dp2[i-1][0] + prices[i]);
            // cout << dp1[i][0] << " "<< dp1[i][1] << " " << dp2[i][0] << " " << dp2[i][1] << endl;
        }
        return dp2[len-1][1];
    }
};

 // 有空间优化
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int len = prices.size();
        int dp10 = -prices[0];
        int dp11 = 0; 
        int dp20 = -prices[0];
        int dp21 = 0;
        for(int i=1;i<len;++i){
            dp21 = max(dp21, dp20 + prices[i]);
            dp20 = max(dp11 - prices[i], max(dp20, -prices[i]));
            dp11 = max(dp11, dp10 + prices[i]);
            dp10 = max(dp10, -prices[i]);
            // 注意顺序
        }
        return dp21;
    }
};

714. 买卖股票的最佳时机含手续费

class Solution {
public:
    int maxProfit(vector<int>& prices, int fee) {
        int len = prices.size();
        int dp[len][2];
        dp[0][0] = -prices[0];
        dp[0][1] = 0;
        for(int i=1;i<len;++i){
            // 注意状态转移
            // 指当前盈亏 (和上一题的不一样)
            dp[i][0] = max(dp[i-1][0], dp[i-1][1] - prices[i]);
            dp[i][1] = max(dp[i-1][0] + prices[i] - fee, dp[i-1][1]); 
        }
        return dp[len-1][1];
    }
};

188. 买卖股票的最佳时机 IV

// 无空间优化
class Solution {
public:
    int maxProfit(int k, vector<int>& prices) {
        int len = prices.size();
        if(len == 0 || k == 0) return 0;
        int dp1[k][len];
        int dp2[k][len];
        for(int i=0;i<k;++i){
            dp2[i][0] = 0;
            dp1[i][0] = -prices[0];
        }
        for(int i=1;i<len;++i){
            dp1[0][i] = max(dp1[0][i-1], -prices[i]);
            dp2[0][i] = max(dp2[0][i-1], dp1[0][i-1] + prices[i]);
            for(int j=1;j<k;++j){
                dp1[j][i] = max(dp1[j][i-1], max(dp2[j-1][i-1] - prices[i], -prices[i]));
                dp2[j][i] = max(dp1[j][i-1] + prices[i], dp2[j][i-1]);
            }
        }
        return dp2[k-1][len-1];
    }
};
// 有空间优化
class Solution {
public:
    int maxProfit(int k, vector<int>& prices) {
        int len = prices.size();
        if(len == 0 || k == 0) return 0;
        int dp1[k];
        int dp2[k];
        for(int i=0;i<k;++i){
            dp1[i] = -prices[0];
            dp2[i] = 0;
        }
        for(int i=1;i<len;++i){
            for(int j=k-1;j>=1;--j){
                dp2[j] = max(dp1[j] + prices[i], dp2[j]);
                dp1[j] = max(dp1[j], max(dp2[j-1] - prices[i], -prices[i]));
            }
            dp2[0] = max(dp2[0], dp1[0]+ prices[i]);
            dp1[0] = max(dp1[0], -prices[i]);
        }
        return dp2[k-1];
    }
};
posted @ 2022-03-02 22:45  fwx  阅读(30)  评论(0)    收藏  举报