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

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

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

1.代码展示

//309.最佳买卖股票时机含冷冻期
int maxProfit(vector& prices) {
	//step1 构建dp数组
	if (prices.size() == 1) {
		return 0;
	}
	vector> dp(prices.size(), vector(4, 0));
	//step2 状态转移方程

	//step3 初始化
	dp[0][0] = -prices[0];
	//step4 开始遍历
	for (int i = 1; i < prices.size(); i++) {
		//持有(前一天持有或者当天购买)
		dp[i][0] = max(dp[i - 1][0], max(dp[i - 1][2] - prices[i] ,dp[i - 1][1] - prices[i]));
		//不持有但不是冷冻期也不是当天卖出
		dp[i][1] = max(dp[i - 1][1], dp[i - 1][2]);
		//冷冻期
		dp[i][2] = dp[i - 1][3];
		//当天卖出
		dp[i][3] = dp[i - 1][0] + prices[i];
	}
	return max(dp[prices.size() - 1][3],max(dp[prices.size() - 1][1], 
		dp[prices.size() - 1][2]));
}

2.本题小节

         思考:本题的重点在于弄懂状态转移方程的由来,如果没有冰冻期的话,我们只需要考虑未持有和持有的两种情况,现在考虑冰冻期的话,就要考虑到四种情况。情况一,持有的情况,持有可能有三种情况,第一种是前一天就持有,第二种是前一天未持有(非冰冻期和当天卖出的情况),第三种是前一天是冰冻期的情况,三种情况选一个max;情况二,不持有的情况(不包含卖出当天和冰冻期),不持有可能有两种情况,前一天不持有,前一天是冰冻期;情况三,是冰冻期,那么前一天必定吃卖出的情况;情况四,当天卖出的情况,前一天必定是持有的情况。

        基本思路:明确为什么会被分为以上四种情况,持有没有分,因为卖完后有冷冻期,持有从一种情况被分为了三种情况,因为卖出要有一种情况,作为冰冻期的参考,那么冰冻期也要有一种情况,剩余的未持有的非冰冻期和非卖出作为了一种情况。在此基础上,明确四个情况之间的关系,防止漏掉。

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

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

1.代码展示

//714.含手续费买卖股票的最佳时机
int maxProfit(vector& prices, int fee) {
	if (prices.size() == 1) {
		return 0;
	}
	//step1 构建dp数组
	vector> dp(prices.size(), vector(2, 0));
	//step2 状态转移方程
	//未持有
	//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])
	//step3 初始化
	dp[0][1] = -prices[0];
	//step4 进入循环
	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][0];
}

2.本题小节

        思考:本题和最佳时机买卖股票2很像,只是在卖股票时多减一个fee即可,本题没有冰冻期,两种状态即可。 

 

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