首页 > 其他分享 >【状态机DP】力扣309. 买卖股票的最佳时机含冷冻期

【状态机DP】力扣309. 买卖股票的最佳时机含冷冻期

时间:2024-10-17 20:50:33浏览次数:9  
标签:力扣 f2 309 int 股票 状态机 prices 冷冻 dp

给定一个整数数组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

动态规划

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int n = prices.size();
        vector<vector<int>> dp(n, vector<int>(3));
        dp[0][0] = -prices[0];
        for(int i = 1; i < n; i++){
            //持有股票
            dp[i][0] = max(dp[i-1][0], dp[i-1][2] - prices[i]);
            //不持有股票且处于冷冻期
            dp[i][1] = dp[i-1][0] + prices[i];
            //不持有股票但不处于冷冻期
            dp[i][2] = max(dp[i-1][1], dp[i-1][2]);
        }
        return max(dp[n-1][1], dp[n-1][2]);
    }
};

时间复杂度:O(n),其中 n 为数组 prices 的长度。
空间复杂度:O(n)。我们需要 3n 的空间存储动态规划中的所有状态,对应的空间复杂度为 O(n)。

我们定义三种情况:
f[i][0]: 手上持有股票的最大收益
f[i][1]: 手上不持有股票,并且处于冷冻期中的累计最大收益
f[i][2]: 手上不持有股票,并且不在冷冻期中的累计最大收益

首先我们来找这三种情况的状态转换方程。
dp[i][0]代表的是持有股票,也就是第i天结束后是持有股票的。那么如何在第i天结束后持有股票呢?它可以选择不操作,当前一天持有股票,那么第i天结束后依旧持有股票。或者是在第i天他买了股票,那么这就说明了第i-1天结束不处于冷冻期并且没有股票,对应代码dp[i-1][2] - prices[i]

dp[i][1]是不持有股票且处于冷冻期,如何才能让在第i天结束的时候处于冷冻期呢?只有在第i天进行了卖的操作,那么第i-1天结束的时候,我们肯定是持有股票的,所以有dp[i][1] = dp[i-1][0] + prices[i];

dp[i][2]是不持有股票但不处于冷冻期,说明我们没有进行买入或者卖出的操作,不然在第i天结束后会持有股票或者处于冷冻期。那么我们不进行操作的话,前一天可以是进行了卖操作然后是冷冻期持续到第i天结束后冷冻期结束,也可以是是前一天也没有进行任何操作,可以从以上两种状态转移而来。 dp[i][2] = max(dp[i-1][1], dp[i-1][2]);

由于最后我们股票需要卖出才能获得最大收益,所以我们只要取dp[n-1][1], dp[n-1][2]两者的最大值即可。

空间优化

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if(prices.empty()){
            return 0;
        }
        int n = prices.size();
        int f0 = -prices[0];
        int f1 = 0;
        int f2 = 0;
        for(int i = 1; i < n; i++){
            int new_f0 = max(f0, f2 - prices[i]);
            int new_f1 = f0 + prices[i];
            int new_f2 = max(f1, f2);
            
            f0 = new_f0;
            f1 = new_f1;
            f2 = new_f2;
        }
        return max(f1, f2);
    }
};

时间复杂度:O(n),其中 n 为数组 prices 的长度。

空间复杂度:使用空间优化,空间复杂度可以优化至 O(1)。

我们可以发现,动态规划中状态方程的转移都来自于前一个i-1状态,那么我们可以使用三个变量来记录三种情况的前一种状态,实现空间优化。

标签:力扣,f2,309,int,股票,状态机,prices,冷冻,dp
From: https://blog.csdn.net/sjsjs11/article/details/142930787

相关文章

  • 【状态机DP】【hard】力扣188. 买卖股票的最佳时机 IV
    给你一个整数数组prices和一个整数k,其中prices[i]是某支给定的股票在第i天的价格。设计一个算法来计算你所能获取的最大利润。你最多可以完成k笔交易。也就是说,你最多可以买k次,卖k次。注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。示例......
  • 力扣刷题_SQL50题
    高频SQL50题(基础版)-学习计划-力扣(LeetCode)全球极客挚爱的技术成长平台602.好友申请II:谁有最多的好友题目:编写解决方案,找出拥有最多的好友的人和他拥有的好友数目。生成的测试用例保证拥有最多好友数目的只有1个人。CreatetableIfNotExistsRequestAccepte......
  • 力扣面试_SQL50题
    高频SQL50题(基础版)-学习计划-力扣(LeetCode)全球极客挚爱的技术成长平台585.2016年的投资CreateTableIfNotExistsInsurance(pidint,tiv_2015float,tiv_2016float,latfloat,lonfloat);TruncatetableInsurance;insertintoInsurance(pid,tiv_2015,......
  • 《GESP5级2309 单选题判断题》 解析(附加编程题)
    温馨提醒,以下解析为个人观点,还是得请大佬多多指教(可以喷,但不能说我是复制粘贴!)一、单选题(每题2分,共30分)1、近年来,线上授课变得普遍,很多有助于改善教学效果的设备也逐渐流行,其中包括⽐较常用的手写板,那么它属于哪类设备?()。A.输入B.输出C.控制D.记录这是一道定义判断的......
  • 代码随想录算法训练营 | 188.买卖股票的最佳时机IV,309.最佳买卖股票时机含冷冻期,714.
    188.买卖股票的最佳时机IV题目链接:188.买卖股票的最佳时机IV文档讲解︰代码随想录(programmercarl.com)视频讲解︰买卖股票的最佳时机IV日期:2024-10-15想法:跟最佳时机III的区别在于dp[i][0]表示的是第i天没有操作,省去了会很麻烦。Java代码如下:classSolution{publicint......
  • 【C语言刷力扣】2206.将数组划分成相等数对
    题目:解题思路:    题目中要求元素成数对出现,即每个元素出现偶数次。用哈希表存放每个数出现的次数,再循环查看每个数的次数是否位偶数。typedefstruct{intkey;intcount;UT_hash_handlehh;}hashEntry;booldivideArray(int*nums,intnumsS......
  • 力扣数据库1045. 买下所有产品的客户
    一、数据1045.买下所有产品的客户-力扣(LeetCode)Customer 表:+-------------+---------+|ColumnName|Type|+-------------+---------+|customer_id|int||product_key|int|+-------------+---------+该表可能包含重复的行。customer_id不......
  • 力扣数据库1193. 每月交易 I
    一、数据表:Transactions+---------------+---------+|ColumnName|Type|+---------------+---------+|id|int||country|varchar||state|enum||amount|int||trans_date|date|+-------......
  • 力扣数据库1174. 即时食物配送 II
    一、数据配送表: Delivery+-----------------------------+---------+|ColumnName|Type|+-----------------------------+---------+|delivery_id|int||customer_id|int||order_date......
  • 【力扣150&Golang】分发糖果
    题目:分发糖果n个孩子站成一排。给你一个整数数组ratings表示每个孩子的评分。你需要按照以下要求,给这些孩子分发糖果:每个孩子至少分配到1个糖果。相邻两个孩子评分更高的孩子会获得更多的糖果。请你给每个孩子分发糖果,计算并返回需要准备的最少糖果数目。示例......