代码随想录 (programmercarl.com)
309.最佳买卖股票时机含冷冻期
可以多次交易买卖股票
1.dp数组及下标的含义
dp[i][0]:持有股票的状态,拥有的最大现金数
dp[i][1]:保持卖出股票的状态
dp[i][2]:卖出股票的状态(此时表示第i天就是卖出了股票,与之前的不持有股票状态有所区别)
dp[i][3]:冷冻期,持续一天
2.递推公式
对于以上四种状态,分别写出其对应的递推公式:
1)保持持股:
dp[i][0] = max(dp[i - 1][0], dp[i - 1][3] - prices[i], dp[i - 1][1] - prices[i]);
维持原样和买入股票两种类型二选一,避免连续两次买入股票的操作(因为不是max)
2)保持卖出股(表示在当天没有卖出操作,只是保持卖出状态,即经历过冷冻期之后一直没有操作):
dp[i][1] = max(dp[i - 1][1], dp[i - 1][3]);
3)卖出股票(就表示在当天卖出):
dp[i][2] = dp[i - 1][0] + prices[i];
4)冷冻期:
dp[i][3] = dp[i - 1][2];
3.初始化
dp[0][0] = - prices[0];
此处初始化的时候,其实dp[0][1],dp[0][2],dp[0][3]在第0天的时候都是非法状态,所以按照定义无法合理化初始值,可以从递推公式入手。
比如当i = 1时,dp[1][0] = dp[0][1] - prices[1],其中dp[1][0]表示的是第1天持股状态下的最大现金,应当为- prices[1],所以根据递推公式可知,dp[0][1] = 0。
其余也可以利用i = 1代入到递推公式之后进行判断。
dp[1][1] = dp[0][3],表示含义为第1天保持卖出状态的最大现金,相当于在第1天当天买入再卖出,即dp[1][1] = 0,所以dp[0][3] = 0。
dp[1][3] = dp[0][2],表示含义为第1天冷冻期状态下的最大现金,此时和上面分析一样,可以理解为当天就进行了买入卖出的操作,dp[1][3] = 0,所以dp[0][2] = 0。
4.遍历顺序
从前往后遍历
class Solution {
public int maxProfit(int[] prices) {
if(prices == null | prices.length == 0){
return 0;
}
int[][] dp = new int[prices.length][4];
dp[0][0] = -prices[0];
dp[0][1] = 0;
dp[0][2] = 0;
dp[0][3] = 0;
for (int i = 1; i < prices.length; i++) {
dp[i][0] = Math.max(dp[i - 1][0], Math.max(dp[i - 1][3] - prices[i], dp[i - 1][1] - prices[i]));
dp[i][1] = Math.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 Math.max(dp[prices.length - 1][1], Math.max(dp[prices.length - 1][2], dp[prices.length - 1][3]));
}
}
5.打印dp数组

714.买卖股票的最佳时机含手续费
可以多次交易买卖股票
和LC122代码几乎一样,需要注意此题的手续费说明【注意:这里的一笔交易指买入持有并卖出股票的整个过程,每笔交易你只需要为支付一次手续费。】
所以手续费只需要在卖出股票的时候交一次即可!
class Solution {
public int maxProfit(int[] prices, int fee) {
if(prices == null | prices.length == 0){
return 0;
}
int[][] dp = new int[prices.length][2];
dp[0][0] = -prices[0];
dp[0][1] = 0;
for (int i = 1; i < prices.length; i++) {
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] - prices[i]);
dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] + prices[i] - fee);
}
return dp[prices.length - 1][1];
}
}
总结

文章讲述了使用动态规划方法求解股票买卖问题,考虑了持有、卖出、冷冻期和手续费的情况。通过dp数组表示不同状态下的最大现金,详细解释了状态转移方程和初始化过程,以及遍历顺序。

154

被折叠的 条评论
为什么被折叠?



