LC.309.最佳买卖股票时机含冷冻期(DP)

传送门

思路:挺好的一个 d p dp dp题,显然每天结束后我们有三种状态,一种是持有股票,一种是不持有股票且在冷冻期,一种是不持有股票不在冷冻期,我们分别设为 d p [ i ] [ 0 ] , d p [ i ] [ 1 ] , d p [ i ] [ 2 ] dp[i][0],dp[i][1],dp[i][2] dp[i][0],dp[i][1],dp[i][2],然后我们对每种状态分析状态转移即可。

对第一种: d p [ i ] [ 0 ] = m a x ( d p [ i − 1 ] [ 0 ] , d p [ i − 1 ] [ 2 ] − a [ i ] ) dp[i][0]=max(dp[i-1][0],dp[i-1][2]-a[i]) dp[i][0]=max(dp[i1][0],dp[i1][2]a[i])

前者保持 i − 1 i-1 i1天持有股票的状态,后者在第 i i i天股票,前提是第 i − 1 i-1 i1天不是冷冻期。

对第二种: d p [ i ] [ 1 ] = d p [ i − 1 ] [ 0 ] + a [ i ] dp[i][1]=dp[i-1][0]+a[i] dp[i][1]=dp[i1][0]+a[i]

显然若第 i i i天处于冷冻期,则说明第 i − 1 i-1 i1天有股票,在第 i i i天卖掉了。

对第三种: d p [ i ] [ 2 ] = m a x ( d p [ i − 1 ] [ 1 ] , d p [ i − 1 ] [ 2 ] ) dp[i][2]=max(dp[i-1][1],dp[i-1][2]) dp[i][2]=max(dp[i1][1],dp[i1][2])

显然可以由这两种状态转移过来。

因为此题的状态都是由前一种转移过来,所以可以考虑空间优化,用三个变量保存前一个状态即可。

时间复杂度: O ( n ) O(n) O(n)

class Solution {
public:
    int maxProfit(vector<int>& a) {
          if(a.empty()) return 0;
          int n=a.size();
          vector<vector<int> >dp(n,vector<int>(3,0));
          dp[0][0]=-a[0];
          for(int i=1;i<n;i++){
              dp[i][0]=max(dp[i-1][2]-a[i],dp[i-1][0]);
              dp[i][1]=dp[i-1][0]+a[i];
              dp[i][2]=max(dp[i-1][1],dp[i-1][2]);
          }
          return max(dp[n-1][1],dp[n-1][2]);
    }
};
class Solution {
public:
    int maxProfit(vector<int>& a) {
          if(a.empty()) return 0;
          int n=a.size();
          vector<int>dp(3,0);
          int x=-a[0],y=0,z=0;
          for(int i=1;i<n;i++){
              dp[0]=max(z-a[i],x);
              dp[1]=x+a[i];
              dp[2]=max(y,z);
              x=dp[0],y=dp[1],z=dp[2];
          }
          return max(y,z);
    }
};