T1:买卖股票的最佳时机
题目要求:
只能买卖一次,求最大利润
dp数组定义:
当前第i天能获得的最大现金
- dp[i][0]: 表示第i天不持有股票
- dp[i][1]: 表示第i天持有股票
状态转移方程:
求最大利润,用最值函数
- dp[i][0]: 如果前一天不持有股票,则第i天继续保持; 如果前一天持有股票,则第i天卖出股票(这样才能保证第i天的时候是处于无股票状态)
dp[i][0] = max(dp[i-1][0] , dp[i-1][1] + prices[i] )
- dp[i][1]: 如果前一天不持有股票,则第i天买入股票(只能买卖这一次);如果前一天持有股票,则第i天保持
dp[i][1] = max( -prices[i] , dp[i-1][1] ) //与-price[i]比较是因为,只考虑当天买卖情况
题目链接:
T2:买卖股票的最佳时机 II
题目要求:
可以买卖多次,求最后的总最大利润
dp数组定义:
同上
状态转移方程:
- dp[i][0]: 如果第i-1天持有股票,则第i天需要卖出;如果第i-1天不持有股票,则第i天保持
dp[i][0] = max(dp[i-1][0] , dp[i-1][1] + prices[i] )
- dp[i][1]: 如果第i-1天不持有股票,则第i天买入; 如果第i-1天持有股票,则第i天保持
这里可以多次买卖,所以比较时不是只与当天买入的价格做对比。
dp[i][1] = max(dp[i-1][0] - prices[i] , dp[i-1][1] )
题目链接:
T3:买卖股票的最佳时机III
题目要求:
限定最多可以买卖两次,即一共可以买卖0、1、2次,求总和最大的利润
dp数组定义:
由于可以最多买卖两次,dp数组的定义需要包括不买卖,买卖一次,买卖两次,分别由dp[i][0]-dp[i][4]来表示第i天无任何操作,第i天第一次持有,第i天不持有(已第一次卖出),第i天第二次持有,第i天不持有(第二次卖出)
状态转移方程:
- dp[i][0]: 第i天0操作,则从头到尾,手头现金都应该是0
- dp[i][1]:第i天持有->第i-1天不持有(从未买过,第i天买入;第i-1天持有,第i天保持
dp[i][1] = max(dp[i-1][0] - price[i],dp[i-1][1])
- dp[i][2]:第i天不持有(第一次卖出)->第i-1天持有,第i天卖出;第i-1天不持有,第i天保持
dp[i][2] = max(dp[i-1][1] + price[i],dp[i-1][2])
- dp[i][3]:第i天持有(已经第二次买入)->第i-1天不持有,第i天第二次买入;第i-1天持有,第i天保持
dp[i][3] = max(dp[i-1][2] - price[i],dp[i-1][3])
- dp[i][4]:第i天不持有(已经第二次卖出)->第i-1天持有,第i天第二次卖出;第i-1天不持有(已经第二次卖出),第i天保持
dp[i][4] = max(dp[i-1][3] + price[i],dp[i-1][4])
取最后一天,五种状态的最大值
题目链接
T4:买卖股票的最佳时机IV
题目要求:
给定参数k,最多可以进行k次买卖
状态转移方程:
generalize 上一题, dp数组定义为dp[i][2 * k + 1] ,分奇偶讨论递推公式
题目链接
T5:买卖股票的最佳时机,含手续费
题目要求:
卖出时考虑fee,可以多次卖出
dp数组定义:
同II
状态转移方程:
- dp[i][0] = max(前一天不持有股票则今天保持.前一天持有股票则今天卖出,但卖出金额需要-手续费)
- dp[i][1] = max(前一天不持有股票则今天买入,前一天持有股票则今天保持)
题目链接:
T6:最佳买卖股票时机,含冷冻期
题目要求:
要求每次卖出之后,相邻的一天不能进行买卖
dp数组定义:
同II
状态转移方程:
- dp[i][0] = max(前一天不持有股票则今天保持.前一天持有股票则今天卖出)
- dp[i][1] = max(前一天不持有股票则今天买入(但是由于冷静期限制,必须从买入的前两天算起),前一天持有股票则今天保持)
这里要注意,如果第i-1天没有买入,则第i-1天的持有利润延续第i-2天,第i天需要买入,则第i天买入之前也延续第i-2天,所以第i天的买入公式可以直接从买入的前两天算起
dp[i][1] = max(dp[i-2][0] - price[i], dp[i-1][1])