• 309. Best Time to Buy and Sell Stock with Cooldown


    参考:团灭股票问题

    base问题:188. Best Time to Buy and Sell Stock IV

    问题:

    股票问题:

    给出一组一支股票每日的价格数组。prices[]

    每一天的操作可以为:买buy,卖sell,不操作rest

    在第二次buy之前,需要离上一次sell隔一天冷静期,求可获得的最大收益是多少。

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

      

    解法:DP(动态规划)

    1.确定【状态】:

    • 当前的天数:第 i 天
    • 当前经过的交易次数:第 k 次
    • 当前的股票持有状况:p:0未持有(待买入),1 持有(待卖出)

    2.确定【选择】:

    • 当前p=0(未持有,待买入状态):
      • 选择 1 :由本日卖出sell导致:dp[i-1][k][1]+prices[i] (昨天持股+今天卖出prices[i])
      • 选择 2:本日不操作rest:  dp[i-1][k][0]             (昨天未持股+今天不操作)
    • 当前p=1(持有,待卖出状态):
      • 选择 1 :由本日买入buy导致:dp[i-2][k][0]-prices[i] (天未持股+今天买入prices[i])
      • 选择 2:本日不操作rest:  dp[i-1][k][1]              (昨天持股+今天不操作)

    3. dp[i][k][p]的含义:

    今天为第i天,交易k次,持有状态为p的状态下,持有的最大收益。

    4. 状态转移:

    dp[i][p]= 

    • 当前p=0(未持有,待买入状态):MAX {
      • 选择 1 :由本日卖出sell导致:dp[i-1][1]+prices[i] (昨天持股+今天卖出prices[i])
      • 选择 2:本日不操作rest:  dp[i-1][0]             (昨天未持股+今天不操作) }
    • 当前p=1(持有,待卖出状态):MAX {
      • 选择 1 :由本日买入buy导致:dp[i-2][0]-prices[i] (前天未持股+今天买入prices[i])
      • 选择 2:本日不操作rest:  dp[i-1][1]              (昨天持股+今天不操作)}

    5. base case:

    • i==0
      • dp[0][0]= 0
      • dp[0][1]= -∞(不可能存在的情况,用-∞表示)
    • 当i==1的时候,求dp[i][1]时,需要知道dp[i-2][0],按照dp[i][1]含义在第一天的时候
      • 由本日买入buy:-princes[i] ->因此,此时相当于dp[i-2][0]=0
      • 本日不操作rest:dp[0][1]

    代码参考:

     1 class Solution {
     2 public:
     3     //dp[i][k][p]: ignore k
     4     //case_1: now without position: = max(sell , rest)
     5     //        dp[i][k][0] = max(dp[i-1][k][1]+prices[i], dp[i-1][k][0])
     6     //case_2: now with position: = max(buy , rest)
     7     //        dp[i][k][1] = max(dp[i-2][k-1][0]-prices[i], dp[i-1][k][1])
     8     //base case:
     9     //dp[0][0] = 0;  0-th day without position
    10     //dp[0][1] = -infinite;  (imposible)0-th day with position
    11     int maxProfit(vector<int>& prices) {
    12         int n = prices.size();
    13         vector<vector<int>> dp(n+1, vector<int>(2, 0));
    14         dp[0][1] = INT_MIN;
    15         for(int i=1; i<=n; i++) {
    16             dp[i][0] = max(dp[i-1][1]+prices[i-1], dp[i-1][0]);
    17             if(i==1) dp[i][1] = -prices[i-1];
    18             else dp[i][1] = max(dp[i-2][0]-prices[i-1], dp[i-1][1]);
    19         }
    20         return dp[n][0];
    21     }
    22 };

    ♻️ 优化:

    空间复杂度:2维->1维

    去掉 i 

    需要前一次的dp[][0], dp[][1] ->dp_0, dp_1

    还有前前一次的dp[][0]  ->dp_0_pre

    代码参考:

    class Solution {
    public:
        int maxProfit(vector<int>& prices) {
            int n = prices.size();
            int dp_0=0, dp_1=INT_MIN;
            int dp_0_pre=0;//if(i==1) dp[i][1] = -prices[i-1];
            for(int i=1; i<=n; i++) {
                int tmp = dp_0;
                dp_0 = max(dp_1+prices[i-1], dp_0);
                dp_1 = max(dp_0_pre-prices[i-1], dp_1);
                dp_0_pre = tmp;
            }
            return dp_0;
        }
    };
  • 相关阅读:
    list extend 和 append
    构建同元素的列表
    Python拷贝(深拷贝deepcopy与浅拷贝copy)
    MySQL之对数据库库表的字符集的更改
    Shell之while循环
    安装keepalived
    Zabbix监控MySQL
    Ganglia监控MySQL
    将Nagios监控信息存入Mysql
    Hadoop之回收站
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/13686215.html
Copyright © 2020-2023  润新知