# DP State Machine

## Leetcode 309. Best Time to Buy and Sell Stock with Cooldown

# Problem

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

# Discussion

We can use a state machine to solve this problem. Detail can be found HERE.

We can have 3 actions:

- buy
- sell
- do nothing (rest)

If we define **s0 **as rest, then from s0:

- we can keep on resting,
- or we can buy

if we buy, we are transmitting to state **s1**.

From state 1, we can

- sell
- keep on doing nothing.

If we doing nothing, we will stay at state s1

if we sell, we will go to a new state **s2**.

From s2, we must go to state s0 to guarantee the cooldown requirement.

The state transition can be visualized here.

# Solution 1

/**

* jimmy shen

* time complexity O(n)

* space complexity O(n)

**/class Solution {

public:

int maxProfit(vector<int>& prices) {

const int n = prices.size();

if (n==0) return 0;

vector<vector<int>> dp(n, vector<int>(3, INT_MIN));

dp[0][0] = 0, dp[0][1] = -prices[0];

for (int i = 1; i < n; ++i)

{

/**

* dp[i][0] is the state of s0 (rest)

* dp[i][1] is the state of s1 (buy)

* dp[i][2] is the state of s2 (sell)

**/

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

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

dp[i][2] = dp[i-1][1] + prices[i];

}

auto ret = max(dp[n-1][0], dp[n-1][2]);

return ret == INT_MIN? 0 : ret;

}

};

# Solution 2

An improved O(1) space complexity solution

/**

* jimmy shen

* time complexity O(n)

* space complexity O(1)

**/class Solution {

public:

int maxProfit(vector<int>& prices) {

const int n = prices.size();

if (n==0) return 0;

int s0 = 0, s1 = -prices[0], s2 = INT_MIN;

int new_s0, new_s1, new_s2;

for (int i = 1; i < n; ++i)

{

new_s0 = max(s0, s2);

new_s1 = max(s1, s0 - prices[i]);

new_s2 = s1 + prices[i];

s0 = new_s0, s1 = new_s1, s2 = new_s2;

}

auto ret = max(s0, s2);

return ret == INT_MIN? 0 : ret;

}

};

Thanks for reading.