# 309. The best time to buy and sell stocks includes freezing period

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

## subject

Given an array of integers, the ith element represents the stock price of the ith day.

Design an algorithm to calculate the maximum profit. You can do as many transactions as you can (buy and sell a stock many times) with the following constraints:

- You can’t participate in multiple transactions at the same time (you have to sell the previous shares before you buy again).
- You can’t buy shares the next day after you sell them.

**Example:**

```
Input: [1,2,3,0,2]
Output: 3
Explanation: the corresponding transaction status is: [buy, sell, freeze period, buy, sell]
```

## Thinking of solving problems

**Idea: dynamic planning**

First examine the topic, the topic that can not participate in multiple transactions at the same time, before buying the need to sell the previous purchase of the stock. There will also be one**Freezing period**The explanation given by the title is that when a stock is sold one day, it can’t be bought again the next day, that is, the day after the sell-off has a rest day.

Because there is such a freezing period in trading, we will first distinguish whether we hold stocks or not, and then add this concept to the discussion. First, two DP arrays are defined, which represent the cumulative maximum return of stocks held and stocks not held respectively.

**State definition**

First, the state is defined, and two arrays are defined`own`

and`not_own`

。 among`own[i]`

Denotes the second`i`

The maximum return on holding shares; and`not_own[i]`

Denotes the second`i`

Days, the maximum return on shares not held.

**state transition **

Let’s talk about it now**Freezing period**This concept, the above two arrays, will have different situations during state transition, as follows:

about`own[i]`

For the first time`i`

The possible split of the maximum return of holding shares for three days is as follows:

- The first
`i-1`

Days hold, days hold`i`

Days to continue to hold; - The first
`i-1`

The first day is the freezing period`i`

Buy the day before yesterday (that is, sell the day before yesterday, buy the day price is`prices[i]`

）； - Then the state transition equation is as follows:
`own[i] = max(own[i-1], not_own[i-2] - prices[i])`

about`not_own[i]`

It can also be divided into the following cases:

- The first
`i-1`

Days, days`i`

It belongs to freezing period; - The first
`i-1`

Day holds stock, day`i`

Sell off the stock in three days; - Then the state transition equation is as follows:
`not_own[i] = max(not_own[i-1], own[i-1]+prices[i])`

Here, a state transition occurs between two arrays. Let’s talk about it first`own[i]`

For the first case, it is easy to understand. For the second case, it is easy to understand, because the income of a close sale is calculated as follows: income = sell buy. Then the money needed to buy on the same day is directly deducted (that is, the purchase price is deducted first). When selling later, this part is not calculated here, and the selling price is directly added. This kind of situation is similar to`not_own[i]`

The second situation is consistent with the first one`i-1`

Days of earnings plus the current stock price (as previously deducted).

**initialization**

`own[0]`

: denotes the second`0`

Days to buy, the previous analysis, here directly minus the purchase price, so`own[0] = -prices[0]`

；

`own[1]`

: indicates that it is possible to`0`

Days to buy, days to buy`1`

Continue to hold; or`1`

I bought on the same day, so`own[1] = max(-prices[0], -prices[1])`

。

`not_own[0]`

: denotes the second`0`

I didn’t hold any stock, so I didn’t make any profit,`not_own[0] = 0`

The specific code implementation is as follows.

## code implementation

```
class Solution:
def maxProfit(self, prices: List[int]) -> int:
if not prices or len(prices) == 1:
return 0
length = len(prices)
own = [0] * length
not_own = [0] * length
#Initialization
own[0] = -prices[0]
own[1] = max(-prices[0], -prices[1])
not_own[0] = 0
for i in range(1, length):
not_own[i] = max(not_own[i-1], own[i-1] + prices[i])
if i == 1:
continue
own[i] = max(own[i-1], not_own[i-2] - prices[i])
return max(own[-1], not_own[-1])
```

## Implementation results

## Welcome to pay attention

The official account [book collection]