【算法练习Day43】最佳买卖股票时机含冷冻期&&买卖股票的最佳时机含手续费

在这里插入图片描述

​个人主页:@Sherry的成长之路
学习社区:Sherry的成长之路(个人社区)
专栏链接:练题
长路漫漫浩浩,万事皆有期待

文章目录

  • 最佳买卖股票时机含冷冻期
  • 买卖股票的最佳时机含手续费
  • 总结:

买卖股票的最后一期了,第一道含冷冻期难一点,第二道含手续费不难,就是之前买卖股票II的模板。

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

309. 最佳买卖股票时机含冷冻期 - 力扣(LeetCode)

这道题难在需要定义更多的dp数组针对第二维状态的定义,它不同于之前讲的那些题。

dp数组的含义:dp【i】【0】还是和之前一样,它代表了持有股票的状态,即包含了买入股票和以前买入现在持有的一个状态。dp【i】【1】我们将其定义为卖出股票后的状态即它是仅代表卖出去股票之后且还未购买新股票的一个状态。dp【i】【2】代表了第i天当天卖出股票的状态,dp【i】【3】代表了卖出股票后的那天冷冻期。我们把之前能够同时表示卖出股票和卖出股票后未持有股票的状态拆分开来,分成了单独的两部分,这是因为买卖股票有一天冷冻期,而我们需要明确确定冷冻期是哪一天,这时我们是需要知道哪一天卖出了股票才能确定冷冻期,这在后面的递推公式也能展示出来。

递推公式:dp【i】【0】根据含义分析一下,它可以由什么状态推出来?持有股票的前一天(也就是继承前一天),冷冻期的后一天再买股票,和冷冻期之后的某一天购买股票,所以说可以由三个状态推出来。

dp【i】【0】=max(dp【i-1】【0】,dp【i-1】【3】-prices【i】,dp【i-1】【1】-prices【i】)

值得关注的是,dp【i-1】【3】-prices【i】,他确实代表了冷冻期的后一天购买股票,只不过这冷冻期后一天购买股票,用的是冷冻期时候所拥有的钱。

dp【i】【1】同样也是由它的前一天的状态和前一天是冷冻期,第一种情况推出不用多说了,很正常的推出,第二种就是新加入的冷冻期概念由于该天的前一天是冷冻期不能购买股票,所以如果当天也没购买那自然就是卖出后未持有股票的状态。

dp【i】【2】是卖出股票的状态,那只能一种情况dp【i-1】【0】+prices【i】也就是持有股票的情况下卖出去。

dp【i】【3】是冷冻期也是一种情况,dp【i-1】【2】,冷冻期啥也干不了所以也就是卖出股票时候有多少钱就是多少钱。

dp数组初始化:dp【0】【0】=-prices【0】就是第一天买股票,就是这么多钱。

其余的状态我们初始化多少呢?其实其他状态在第一天都是非法的状态,我们可以这样想,第一天买第一天卖那肯定就是不赚钱就是0,而不持有股的状态也是0,冷冻期和卖出股票时候一样所以也是0。更靠谱一点的数学推理,我们可以带入递推公式,按情况来初始化,这一方面大家也可以把数据自己带入,试一试,也就知道了第一次初始化应该为多少。

遍历顺序:是正常的从前向后

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        vector<vector<int>>dp(prices.size(),vector<int>(4,0));
        dp[0][0]=-prices[0];
        for(int i=1;i<prices.size();i++){
            dp[i][0]=max(dp[i-1][0],max(dp[i-1][3]-prices[i],dp[i-1][1]-prices[i]));
            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];
        }
        return max(dp[prices.size()-1][1],max(dp[prices.size()-1][2],dp[prices.size()-1][3]));
    }
};

这道题因为状态多,要确定每个状态的含义,只有确定清楚才能够解出题解。

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

714. 买卖股票的最佳时机含手续费 - 力扣(LeetCode)

这道题也是可以重复买卖股票的题,与买卖股票II的唯一区别仅在于每次买卖需要交一次手续费,这其实就购买股票时候加上一次手续费,就可以了,代码方面没有大改动,不懂得去看上两篇文章。

class Solution {
public:
    int maxProfit(vector<int>& prices, int fee) {
        vector<vector<int>>dp(prices.size(),vector<int>(2,0));
        dp[0][0]=-prices[0]-fee;
        for(int i=1;i<prices.size();i++){
            dp[i][0]=max(dp[i-1][0],dp[i-1][1]-prices[i]-fee);
            dp[i][1]=max(dp[i-1][1],dp[i-1][0]+prices[i]);
        }
        return dp[prices.size()-1][1];
    }
};

总结:

今天我们完成了最佳买卖股票时机含冷冻期、买卖股票的最佳时机含手续费两道题,相关的思想需要多复习回顾。接下来,我们继续进行算法练习。希望我的文章和讲解能对大家的学习提供一些帮助。

当然,本文仍有许多不足之处,欢迎各位小伙伴们随时私信交流、批评指正!我们下期见~

在这里插入图片描述

你可能感兴趣的:(练题,算法)