121.买卖股票的最佳时机
思路:
- 状态定义
状态表示:
状态方程
=
{
d
p
[
i
]
[
0
]
=
表示第
i
天交易完后,手上没有股票时的最大利润,
d
p
[
i
]
[
1
]
=
表示第
i
天交易完后,手上持有股票时的最大利润。
状态方程 = \begin{cases} dp[i][0] =表示第 i 天交易完后,手上 没有 股票时的最大利润,\\ dp[i][1] =表示第 i 天交易完后,手上 持有 股票时的最大利润。 \end{cases}
状态方程={dp[i][0]=表示第i天交易完后,手上没有股票时的最大利润,dp[i][1]=表示第i天交易完后,手上持有股票时的最大利润。
- 状态转移
状态转移方程为:
{ d p [ i ] [ 0 ] = m a x ( d p [ i − 1 ] [ 0 ] , d p [ i − 1 ] [ 1 ] + p r i c e s [ i ] ) d p [ i ] [ 1 ] = m a x ( d p [ i − 1 ] [ 1 ] , − p r i c e s [ i ] ) \begin{cases} dp[i][0] = max(dp[i-1][0],dp[i-1][1]+prices[i]) \\ dp[i][1] = max(dp[i-1][1],-prices[i]) \end{cases} {dp[i][0]=max(dp[i−1][0],dp[i−1][1]+prices[i])dp[i][1]=max(dp[i−1][1],−prices[i])
如果第i天不持有股票即dp[i] [0], 也可以由两个状态推出来
- 第i-1天就不持有股票,那么就保持现状,所得现金就是昨天不持有股票的所得现金 即:dp[i - 1] [1]
- 第i天卖出股票,所得现金就是按照今天股票价格卖出后所得现金即:prices[i] + dp[i - 1] [0]
dp[i] [0]取最大的,dp[i] [0] = max(dp[i - 1] [0], prices[i] + dp[i - 1] [1]);
如果第i天持有股票即dp[i] [1], 那么可以由两个状态推出来
- 第i-1天就持有股票,那么就保持现状,所得现金就是昨天持有股票的所得现金 即:dp[i - 1] [1]
- 第i天买入股票,所得现金就是买入今天的股票后所得现金即:-prices[i]
那么dp[i] [1]应该选所得现金最大的,所以dp[i] [1] = max(dp[i - 1] [1], -prices[i]);
- 初始化
对第一天(i=0)的状态进行初始化:
dp[0] [0]: 第一天手上无股票,也没有购入股票。
dp[0] [1]: 第一天手上持有股票说明在当天购入了股票,花费 prices[0]prices[0]prices[0],即所获利润为 −prices[0]。
- 执行结果
遍历全部的日期i,则最后一天手上没有股票时的状态值dp[n-1] [0]即为我们能够获得的最大利润。
class Solution:
def maxProfit(self, prices: List[int]) -> int:
n = len(prices)
# dp[i][0]:第i天结束后,手上没有股票的最大利润(第i天卖出股票 )
# dp[i][1]:第i天结束后,手术持有股票的最大利润(第i天买入股票)
dp = [[0]*2 for _ in range(n)]
# 初始化
dp[0][0] = 0
dp[0][1] = -prices[0]
for i in range(1,n):
# dp[i][0]:max(前一天没有股票,前一天持有股票+当天卖出)
dp[i][0] = max(dp[i-1][0],dp[i-1][1]+prices[i])
# dp[i][1]:max(前一天持有股票,前一天没有股票+当天买入)
dp[i][1] = max(dp[i-1][1],-prices[i])
return max(dp[n-1][0],dp[n-1][1])
# return dp[n - 1][0
122.买卖股票的最佳时机II
思路:
- 状态定义
状态表示:
状态方程
=
{
d
p
[
i
]
[
0
]
=
表示第
i
天交易完后,手上没有股票时的最大利润,
d
p
[
i
]
[
1
]
=
表示第
i
天交易完后,手上持有股票时的最大利润。
状态方程 = \begin{cases} dp[i][0] =表示第 i 天交易完后,手上 没有 股票时的最大利润,\\ dp[i][1] =表示第 i 天交易完后,手上 持有 股票时的最大利润。 \end{cases}
状态方程={dp[i][0]=表示第i天交易完后,手上没有股票时的最大利润,dp[i][1]=表示第i天交易完后,手上持有股票时的最大利润。
- 状态转移
状态转移方程为:
{ d p [ i ] [ 0 ] = m a x ( d p [ i − 1 ] [ 0 ] , d p [ i − 1 ] [ 1 ] + p r i c e s [ i ] ) d p [ i ] [ 1 ] = m a x ( d p [ i − 1 ] [ 1 ] , d p [ i − 1 ] [ 0 ] − p r i c e s [ i ] ) \begin{cases} 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]) \end{cases} {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])
- 初始化
对第一天(i=0)的状态进行初始化:
dp[0] [0]: 第一天手上无股票,也没有购入股票。
dp[0] [1]: 第一天手上持有股票说明在当天购入了股票,花费 prices[0],即所获利润为 −prices[0]。
- 执行结果
遍历全部的日期i,则最后一天手上没有股票时的状态值dp[n-1] [0]即为我们能够获得的最大利润。
class Solution:
def maxProfit(self, prices: List[int]) -> int:
n = len(prices)
# dp[i][0]:第i天结束后,手上没有股票的最大利润(第i天卖出股票 )
# dp[i][1]:第i天结束后,手术持有股票的最大利润(第i天买入股票)
dp = [[0]*2 for _ in range(n)]
# 初始化
dp[0][0] = 0
dp[0][1] = -prices[0]
for i in range(1,n):
# dp[i][0]:max(前一天没有股票,前一天持有股票+当天卖出)
dp[i][0] = max(dp[i-1][0],dp[i-1][1]+prices[i])
# dp[i][1]:max(前一天持有股票,前一天没有股票+当天买入)
dp[i][1] = max(dp[i-1][1],dp[i-1][0]-prices[i])
return max(dp[n-1][0],dp[n-1][1])
# return dp[n - 1][0]