tasks for today (股票买卖专题):
1. 188.买卖股票的最佳时机IV
2. 309.买卖股票最佳时机含冷冻期
3. 714.买卖股票最佳时机含手续费
-----------------------------------------------------------------------------
1. 188.买卖股票的最佳时机IV
This practice is a escalated varaint of practice 123 by extending the trading times from 2 to k.
class Solution:
def maxProfit(self, k: int, prices: List[int]) -> int:
if len(prices) == 1: return 0
if len(prices) == 2: return max(0, prices[1]-prices[0])
dp = [[0] * (2 * k + 1) for _ in range(len(prices))]
dp[0][0] = 0
for i in range(1, 2 * k + 1, 2):
dp[0][i] = -prices[0]
for i in range(1, len(prices)):
dp[i][0] = dp[i-1][0]
curprice = prices[i]
for j in range(1, 2*k+1):
curprice *= -1
dp[i][j] = max(dp[i-1][j], dp[i-1][j-1] + curprice)
return dp[-1][-1]
2. 309.买卖股票最佳时机含冷冻期
In this practice, the key is to discriminate all the state relate to the trading: which should be discerned as 0:holding stock, 1:not holding stock-remain, 2:not holding stock-sell, 3:frozen.
The two states "1:not holding stock-remain, 2:not holding stock-sell" used to be combined together as one state in previous practices, but here they are separated into two states, which is because the existence of the state frozen. Because "frozen" state can only be right after the state of "2:not holding stock-sell", cannot be after any other state, including "1:not holding stock-remain". Therefore, if we still remain the setting of using "not holding stock" as one single state including both remaining and selling, it will be unclear in this practice's special setting with "frozen" state.
pay attention to the return value, which is the maximum among state 1,2,3.
class Solution:
def maxProfit(self, prices: List[int]) -> int:
if len(prices) == 1: return 0
if len(prices) == 2: return max(0, prices[1]-prices[0])
dp = [[0] * 4 for _ in range(len(prices))]
dp[0][0] = -prices[0]
dp[0][1] = 0
dp[0][2] = 0
dp[0][3] = 0
for i in range(1, len(prices)):
dp[i][0] = max(dp[i-1][0], dp[i-1][1]-prices[i], dp[i-1][3]-prices[i])
dp[i][1] = max(dp[i-1][1], dp[i-1][3])
dp[i][2] = dp[i-1][0] + prices[i]
dp[i][3] = dp[i-1][2]
return max(dp[-1][1], dp[-1][2], dp[-1][3])
3. 714.买卖股票最佳时机含手续费
In this practice, there would be a fee incurred by each trading (in & and as once), so this practice is basically the same with the practice 122, the key difference is the fee. This fee should be counted ahering a specific action, which is trading out, i.e., every time when there is an action of trading out, an additional trading fee should be deduct.
class Solution:
def maxProfit(self, prices: List[int], fee: int) -> int:
if len(prices) == 1: return 0
if len(prices) == 2: return max(0, prices[1]-prices[0]-fee)
dp = [[0] * 2 for _ in range(len(prices))]
dp[0][0] = -prices[0]
dp[0][1] = 0
for i in range(1, len(prices)):
dp[i][0] = max(dp[i-1][0], dp[i-1][1]-prices[i])
dp[i][1] = max(dp[i-1][1], dp[i-1][0]+prices[i]-fee)
return dp[-1][1]