动态规划中的股票问题汇总记录
一次买卖
1 | //第一种方法:记录到i-1为止,最小下标,然后比较prices[i]-prices[currintMinIndex] |
容易理解的写法
1 | int maxProfit(vector<int> &prices) |
1 | //第二种方法:计算prices[i]-price[i-1],然后题目就可以转为连续数组最大值问题 |
不限次数(https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/)
1 | int maxProfit(vector<int>& prices) |
两次买卖
最多两次买卖
1 | int maxProfit(vector<int> &prices) |
K次买卖
动态规划:global[i][j]的意义是第i天以及之前最多进行j次交易所能获得的最大利润,local[i][j]的意义是在第i天以及之前最多进行j次交易且在第i天卖出股票所能得到的最大利润(如果global[i][j]是在第i天卖出,则global[i][j]=local[i][j]),地推公式为:
解释:
local公式:$global[i-1][j-1]+max(diff,0)$的意思是global[i-1][j-1]必然不可能在第i-1天买入(买入就没办法卖出了,利润自然要小),如果diff>0则在加上i-1天买,第i天卖的利润(一共j次交易),否则就不算了(一共j-1次交易)。$local[i - 1][j] + diff$的意思是$第i-1天不卖了,改为第i天卖.
gobal公式较简单,不解释.
1 | int maxProfitK(int k, vector<int> &prices) |
空间优化
1 | int maxProfitK(int k, vector<int> &prices) |
注意,当k>prices.size()/2的时候其实就退化成了不限次数问题,因此这里可以做一些优化.
股票冷冻期
Leetcode309
动态规划:
buy[i]数组:第i天以及之前最后一个操作是buy所能得到的最大利润
sell[i]数组:第i天以及之前最后一个操作是sell所能得到的最大利润
cooldown[i]数组:第i天以及之前最后一个操作是cooldown所能得到的最大利润
地推公式为:解释:
每一个公式的前一项都表示在第i天不进行相应的操作会怎样,第二项表示在第i天进行相应的操作会怎样.
buy:第一项表示如果在第i天不buy,则自然$buy[i]=buy[i-1]$,如果在第i天buy,则buy之前的状态必然是cooldown,因此$buy[i]=cooldown[i-1]-prices[i]$
sell:第一项表示如果在第i天不sell,则自然$sell[i]=sell[i-1]$,如果在第i天sell,则sell之前的状态必然是buy,因此$sell[i]=buy[i-1]+prices[i]$
cooldown:第一项表示如果在第i天cooldown,则自然$cooldown[i]=cooldown[i-1]$,如果在第i天cooldown,则cooldown[i]=max(sell[i-1],buy[i-1])
1 | int maxProfit(vector<int> &prices) |
由于$cooldown[i] = sell[i-1]$(cooldown[i]的意思是i以及之前的最后一次操作是cooldown,也就是i-1以及之前的最后一次操作是sell,也就是sell[i-1])
地推公式可以归位两个:
1 | int maxProfit(vector<int> &prices) |
最后优化
1 | int maxProfit(vector<int>& prices) |