代码随想录算法训练营第五十一天| 309.最佳买卖股票时机含冷冻期,714.买卖股票的最佳时机含手续费,总结

 题目与题解

参考资料:买卖股票总结

309.最佳买卖股票时机含冷冻期

题目链接:309.最佳买卖股票时机含冷冻期

代码随想录题解:309.最佳买卖股票时机含冷冻期

视频讲解:动态规划来决定最佳时机,这次有冷冻期!| LeetCode:309.买卖股票的最佳时机含冷冻期_哔哩哔哩_bilibili

解题思路:

        听说状态比较多,直接放弃看答案,状态转移有点复杂的。

看完代码随想录之后的想法 

        关键是要理解在有冷冻状态的条件下,股票可能有哪些状态,它们之间的关系是什么,才能直到状态变化的依赖关系,得出状态转移公式。

具体可以区分出如下四个状态:

  • 状态一:持有股票状态(今天买入股票,或者是之前就买入了股票然后没有操作,一直持有)
  • 不持有股票状态,这里就有两种卖出股票状态
    • 状态二:保持卖出股票的状态(两天前就卖出了股票,度过一天冷冻期。或者是前一天就是卖出股票状态,一直没操作)
    • 状态三:今天卖出股票
  • 状态四:今天为冷冻期状态,但冷冻期状态不可持续,只有一天!

        

那么转移到状态一有三种情况:保持买入状态不变,不买不卖(状态1->1);刚结束冷冻状态,直接买入(状态4->1);处于卖出一段时间的状态,再买入(状态2->1)

转移到状态2有两种情况:前面没有冷冻,保持卖出状态不变,不买不卖(状态2->2);刚结束冷冻状态,但不买入,保持卖出状态(状态4->2)

转移到状态3只有一种情况:处于买入状态,然后卖出(状态1->3)

转移到状态4只有一种情况:刚卖出(状态3->4)

递推公式根据状态转移就可以清楚的得到了。初始化状态1为-prices[0],其余状态由于还未产生交易,初始化为0。

最后返回时,要从状态2,3,4中选一个最大值。因为今天卖出,冷冻,和保持卖出状态这三种都属于卖出的状态,有可能都有最大值。

class Solution {
    public int maxProfit(int[] prices) {
		if (prices.length <= 1) return 0;
		int[][] dp = new int[prices.length][4];
		dp[0][0] = -prices[0];
		for (int i = 1; i < prices.length; i++) {
			dp[i][0] = Math.max(dp[i-1][0], Math.max(dp[i-1][1]-prices[i], dp[i-1][3]-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]));
    }
}

遇到的困难

        第一次遇到这么复杂的状态,记下了

714.买卖股票的最佳时机含手续费

题目链接:714.买卖股票的最佳时机含手续费

代码随想录题解:714.买卖股票的最佳时机含手续费

视频讲解:动态规划来决定最佳时机,这次含手续费!| LeetCode:714.买卖股票的最佳时机含手续费_哔哩哔哩_bilibili

解题思路:

        这题跟买卖股票II几乎一样,就是在卖出状态时,如果卖出了股票,需要增加一个手续费,即dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0] + prices[i] - fee)。最后仍旧返回dp[prices.length-1][1]即可。

class Solution {
    public int maxProfit(int[] prices, int fee) {
		if (prices.length <= 1) 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[i][0]递推公式的时候一开始思路不清晰写成了dp[i-1][0] - prices[i],这肯定不对,要牢记卖出后才能买入,必然用dp[i-1][1] - prices[i]来递推。

今日收获

       学习了一下复杂状态的买卖股票方法, 复习总结了买卖股票系列问题。

        买卖股票问题的核心解法是定义dp为手中持有的现金,再根据买入卖出加减持有值。

        买卖一次和买卖多次的状态转移方法有点类似,最后可以用公式总结出来;如果出现类似冷冻期,手续费之类的特殊值,需要判断其状态转移是否有变化,递推公式是否需要修改,基本公式就是买卖股票IV里的规律总结了。

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-04-26 08:20:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-26 08:20:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-26 08:20:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-26 08:20:02       20 阅读

热门阅读

  1. 【vivado】vivado导出hardware问题

    2024-04-26 08:20:02       44 阅读
  2. CSS接触

    2024-04-26 08:20:02       16 阅读
  3. 上海计算机学会 2024年4月月赛 丙组T4 排序分数

    2024-04-26 08:20:02       14 阅读
  4. 配置etcd、apiserver使用的cpu和内存资源

    2024-04-26 08:20:02       41 阅读
  5. windows ubuntu:sed,awk,grep篇:3,sed正则表达式

    2024-04-26 08:20:02       25 阅读
  6. QML中调用HTTP请求

    2024-04-26 08:20:02       21 阅读
  7. conda环境查看当前可下载的Django版本

    2024-04-26 08:20:02       13 阅读
  8. K8S Service 常见问题

    2024-04-26 08:20:02       16 阅读
  9. 2-token生成

    2024-04-26 08:20:02       12 阅读
  10. 每天学习一个Linux命令之awk

    2024-04-26 08:20:02       14 阅读
  11. mysql 意向锁

    2024-04-26 08:20:02       13 阅读
  12. 46、有向图的拓扑序列

    2024-04-26 08:20:02       12 阅读