• 代码随想录第五十天|123.买卖股票的最佳时机III、188.买卖股票的最佳时机IV


    123.买卖股票的最佳时机III

    题目链接/文章讲解/视频讲解:代码随想录

     1.代码展现

    1. //123.买卖股票的最佳时机
    2. int maxProfit(vector<int>& prices) {
    3. if (prices.size() == 1) {
    4. return 0;
    5. }
    6. //step1 构建dp数组
    7. vectorint>> dp(prices.size(), vector<int>(5, 0));
    8. //dp[i][0]的含义是
    9. //dp[i][1]的含义是第一次持有股票的最大金额数
    10. //dp[i][2]的含义是第一次未持有(卖掉了)股票的最大金额数
    11. //dp[i][3]的含义是第二次持有股票的最大金额数
    12. //dp[i][4]的含义是第二次未持有(卖掉了)股票的最大金额数
    13. //step2 状态转移方程
    14. //dp[i][1] = max(dp[i - 1][1], -prices[i])
    15. //dp[i][2] = max(dp[i - 1][2], dp[i - 1][1] + prices[i])
    16. //dp[i][3] = max(dp[i - 1][3], dp[i - 1][2] - prices[i])
    17. //dp[i][4] = max(dp[i - 1][4], dp[i - 1][3] + prices[i])
    18. //step3 初始化dp数组
    19. dp[0][1] = -prices[0];
    20. dp[0][3] = -prices[0];
    21. //step4 开始遍历
    22. for (int i = 1; i < prices.size(); i++) {
    23. dp[i][1] = max(dp[i - 1][1], -prices[i]);
    24. dp[i][2] = max(dp[i - 1][2], dp[i - 1][1] + prices[i]);
    25. dp[i][3] = max(dp[i - 1][3], dp[i - 1][2] - prices[i]);
    26. dp[i][4] = max(dp[i - 1][4], dp[i - 1][3] + prices[i]);
    27. }
    28. return dp[prices.size() - 1][4];
    29. }

    2.本题小节

            思考:本题与昨天的题目不同点在于可以购买两次,因此第i天一共有四种状态,第一次持有,第一次未持有,第二次持有,第二次未持有,每次都有对应的状态转移公式,第一次持有的话,两种情况,前一天的,或者是当天买的;第一次未持有,要么就是前一天未持有,或者是今天卖的,是前一天持有的金钱加上卖票的金钱,第二次持有的同理。同时注意每一次持有的初始化,即-price[0]。 

            基本思路:明确状态转移公式和初始化。

    188.买卖股票的最佳时机IV 

     题目链接/文章讲解/视频讲解:代码随想录

    1.本题小节

    1. //188 买卖股票的最佳时机
    2. int maxProfit(int k, vector<int>& prices) {
    3. if (prices.size() == 1) {
    4. return 0;
    5. }
    6. //step1 构建dp数组
    7. vectorint>> dp(prices.size(), vector<int>(2 * k + 1, 0));
    8. //step2 状态转移方程
    9. //step3 初始化
    10. for (int j = 0; j < 2 * k; j += 2) {
    11. dp[0][j + 1] = -prices[0];
    12. }
    13. //step4 开始遍历
    14. for (int i = 1; i < prices.size(); i++) {
    15. for (int j = 0; j < 2 * k; j += 2)
    16. {
    17. //持有股票
    18. dp[i][j + 1] = max(dp[i - 1][j + 1], dp[i - 1][j] - prices[i]);
    19. //未持有股票
    20. dp[i][j + 2] = max(dp[i - 1][j + 2], dp[i - 1][j + 1] + prices[i]);
    21. }
    22. }
    23. return dp[prices.size() - 1][2 * k];
    24. }

    2.本题小节

            思考:本题是可以买卖k次,通过上一题可以找到规律,主要是明确状态转移公式,要对1-k次依次创建状态转移公式,每天k次的状态都是持有和不持有两种,因此状态转移方程共有2k个,但是每次的的两种情况规律是一样的,每次持有的状态是两种情况,前一天的持有状态,或者是前一天未持有的状态减去prices[i];未持有的状态也是两种情况,前一天未持有的状态,或者是今天卖出股票的状态。注意初始化和上一题一样,但是有k次初始化,需要for循环遍历。

            基本思路:明确状态转移公式和初始化。

  • 相关阅读:
    基于 SpringBoot 的智慧养老平台,附源码、教程
    荔枝集团:如何提升项目管理效能,让需求交付快进50%
    389. 找不同(简单不一定知道)
    575.分糖果
    【STL】string类 (上)& <vector>和<list>的简单使用
    asp.net教师调课系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio
    0901(044天 集合框架08 树TreeMap)
    hexo博客主题推荐
    Nginx Rewrite
    Python 面向对象初步
  • 原文地址:https://blog.csdn.net/weixin_62453859/article/details/132609716