Day53 代码随想录算法训练营 第九章 动态规划 part12|309.最佳买卖股票时机含冷冻期、714.买卖股票的最佳时机含手续费 、总结

今日内容

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

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

总结

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

问题:

给定一个整数数组prices,其中第  prices[i] 表示第 i 天的股票价格 。​

设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):

  • 卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

 提示:

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

思路:

注意:无法在第二天买入股票 (即冷冻期为 1 天)

① dp数组

dp[i][j]:第i天状态为j,所剩的最多现金为dp[i][j]。

i:[0, prices.length )

j: [0, 2*k+1)

状态:持有、不持有、冷冻

  • dp[i][0]:持股(包含当天买入,以及之前买入)
  • dp[i][1]:保持卖出状态
  • dp[i][2]:卖出股票
  • dp[i][3]:冷冻期

持有股票状态:dp[i][0]

① 当天买入(前一天是 冷冻期状态: dp[i-1][3]-prices[i])(前一天是   保持卖出股票的状态:dp[i-1][1]-prices[i])

② 前一天就持有股票了  dp[i-1][0]

保持卖出状态:dp[i][1]

①(前一天就是卖出状态了 dp[i-1][1])

②(当前是冷冻期,保持着卖出的状态 dp[i-1][3] )

卖出:dp[i][2]

当天卖出(dp[i-1][0] + prices[i])

冷冻期:dp[i][3]

前一天一定是卖出状态(dp[i-1][2])

② 递推公式

dp[i][0] = max(dp[i-1][3]-prices[i], 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]

③ 初始化(从递推公式中看,需要我们将其初始化为多少)

dp[0][0] = -prices[0]

dp[0][1] = 0

dp[0][2] = 0

dp[0][3] = 0

④ 循环遍历

从前往后遍历

 

⑤ 举例推导dp数组

 

 

 

最后,取dp[len-1][1] dp[len-1][2] dp[len-1][3]得最大值

 

 

代码:

 1 /*
 2  * @lc app=leetcode.cn id=309 lang=javascript
 3  *
 4  * [309] 买卖股票的最佳时机含冷冻期
 5  */
 6 
 7 // @lc code=start
 8 /**
 9  * @param {number[]} prices
10  * @return {number}
11  */
12 var maxProfit = function(prices) {
13     let dp = new Array(prices.length).fill(0).map(() => new Array(4).fill(0))
14 
15     dp[0][0] = -prices[0];
16 
17     for (let i = 1; i < prices.length; i++) {
18         dp[i][0] = Math.max(dp[i - 1][0], Math.max(dp[i - 1][3] - prices[i], dp[i - 1][1] - prices[i]))
19         dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][3])
20         dp[i][2] = Math.max(dp[i - 1][0] + prices[i])
21         dp[i][3] = Math.max(dp[i - 1][2])
22 
23 
24     }
25     let len = prices.length - 1;
26     return Math.max(dp[len][1], Math.max(dp[len][2], dp[len][3]))
27 };

 

 

 

 

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

问题:

给定一个整数数组 prices,其中 prices[i]表示第 i 天的股票价格 ;整数 fee 代表了交易股票的手续费用。

你可以无限次地完成交易,但是你每笔交易都需要付手续费。如果你已经购买了一个股票,在卖出它之前你就不能再继续购买股票了。

返回获得利润的最大值。

注意:这里的一笔交易指买入持有并卖出股票的整个过程,每笔交易你只需要为支付一次手续费。

 提示:

  • 1 <= prices.length <= 5 * 104
  • 1 <= prices[i] < 5 * 104
  • 0 <= fee < 5 * 104

思路:

类似122. 两个状态 0(持有)1 (不持有)

直接AC

 1 /*
 2  * @lc app=leetcode.cn id=714 lang=javascript
 3  *
 4  * [714] 买卖股票的最佳时机含手续费
 5  */
 6 
 7 // @lc code=start
 8 /**
 9  * @param {number[]} prices
10  * @param {number} fee
11  * @return {number}
12  */
13 var maxProfit = function(prices, fee) {
14     let dp = new Array(prices.length).fill(0).map(() => new Array(2).fill(0))
15     dp[0][0] = -prices[0];
16     dp[0][1] = 0;
17 
18     for (let i = 1; i < prices.length; i++) {
19         dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] - prices[i])
20         dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] + prices[i] - fee)
21 
22     }
23     return dp[prices.length - 1][1];
24 };

 

股票问题总结

 

posted @ 2023-10-17 15:00  子酱  阅读(62)  评论(0)    收藏  举报