【算法|动态规划】Leetcode 309.买卖股票的最佳时机含冷冻期
本文最后更新于 426 天前,其中的信息可能已经有所发展或是发生改变。
37.买卖股票的最佳时机冷冻期

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


题目描述

  • 给定一个整数数组prices,其中第 prices[i] 表示第 i 天的股票价格 。​
  • 设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):
  • 卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。
    注意: 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

示例1:

输入: prices = [1, 2, 3, 0, 2]
输出: 3
解释: 对应的交易状态为: [买入, 卖出, 冷冻期, 买入, 卖出]

示例2:

输入: prices = [1]
输出: 0

提示:

  • 1 <= prices.length <= 5000
  • 0 <= prices[i] <= 1000

解题思路

  1. 确定dp数组以及下标的含义
  2. dp[i][j] 表示第i天j状态下股票所得的最多现金
  • dp[i][0]持有股票的状态

    • 第i天买入
    • 第i-1天持有,第i天不操作, 保持持有状态
  • dp[i][1]保持卖出股票的状态

    • 冷冻期后的1天或n天
  • dp[i][2]实际卖出股票的状态,特指在第i天卖出股票 → 下一天为冷冻期

  • dp[i][3]冷冻期的状态

  1. 递推公式
  • dp[i][0]持有股票

    • 第i天买入:看前一天状态

      • 前一天为冷冻期:dp[i][0] = dp[i-1][3] - prices[i]
      • 前一天为保持卖出状态:dp[i][0] = dp[i-1][1] - prices[i]
    • 第i-1天持有:dp[i][0] = dp[i-1][0] dp[i][0] = max(dp[i-1][3] - prices[i], dp[i-1][1] - prices[i], dp[i-1][0])

  • dp[i][1]保持卖出股票状态

    • 第i-1天保持卖出股票状态:dp[i][1] = dp[i-1][1]
    • 第i-1天保冷冻期状态:dp[i][1] = dp[i-1][3] dp[i][1] = max(dp[i-1][1], dp[i-1][3])
  • dp[i][2]实际卖出股票,前一天持有, 后一天冷冻期 dp[i][2] = dp[i-1][0] + prices[i]

  • dp[i][3]: 冷冻期,前一天必须卖出股票 dp[i][3] = dp[i - 1][2]

  1. dp数组初始化
  • dp[0][0] = -prices[0]
  • dp[0][1] = 0:根据递推公式来初始化
  • dp[0][2] = 0:同上
  • dp[0][3] = 0:第一天冷冻期,根据递推公式初始化为0
  1. 确定遍历顺序
  2. 根据递推公式可以看出,dp[i] 都是由 dp[i-1] 推出来的,那么遍历顺序一定是从前往后遍历
  3. 打印dp数组

代码实现

  • 核心模式
class Solution{
public:
    int maxProfit(vector<int>& prices){
        int len = prices.size();
        if (len == 0) return 0;

        vector<vector<int>> dp(len, vector<int>(4, 0));

        //initialize the DP array
        dp[0][0] = -prices[0];

        for (int i = 1; i < len; i++){
            dp[i][0] = max(dp[i - 1][3] - prices[i], max(dp[i - 1][1] - prices[i], dp[i - 1][0]));
            dp[i][1] = 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];
        }

        // The maxProfit may appear in state1, state2 and state3
        return max(dp[len - 1][1], max(dp[len - 1][2], dp[len - 1][3]));
    }
};
#include <iostream>
#include "dynamicPro.h"

class Solution{
public:
    int maxProfit(const vector<int>& prices){
        using std::max;
        int len = prices.size();
        if (len == 0) return 0;

        vector<vector<int>> dp(len, vector<int>(4, 0));

        //initialize the DP array
        dp[0][0] = -prices[0];

        for (int i = 1; i < len; i++){
            dp[i][0] = max(dp[i - 1][3] - prices[i], max(dp[i - 1][1] - prices[i], dp[i - 1][0]));
            dp[i][1] = 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];
        }

        print2DVector(dp);

        // The maxProfit may appear in state1, state2 and state3
        return max(dp[len - 1][1], max(dp[len - 1][2], dp[len - 1][3]));
    }
};

int main(){
    vector<int> case1 = {1, 2, 3, 0, 2};
    vector<int> case2 = {1};

    Solution solution;
    cout << "Result1's DP array = " << solution.maxProfit(case1) << endl;
    cout << "Result2's DP array = " << solution.maxProfit(case2) << endl;
}
  • 输出
Result1's DP array = [[-1, 0, 0, 0], [-1, 0, 1, 0], [-1, 0, 2, 1], [1, 1, -1, 2], [1, 2, 3, -1]]
3
Result2's DP array = [[-1, 0, 0, 0]]
0
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇