309\. 最佳买卖股票时机含冷冻期
# 309. 最佳买卖股票时机含冷冻期 (opens new window)
# Description
Difficulty: 中等
Related Topics: 数组 (opens new window), 动态规划 (opens new window)
给定一个整数数组prices
,其中第 prices[i]
表示第 _i_
天的股票价格 。
设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):
- 卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。
**注意:**你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
示例 1:
输入: prices = [1,2,3,0,2]
输出: 3
解释: 对应的交易状态为: [买入, 卖出, 冷冻期, 买入, 卖出]
1
2
3
2
3
示例 2:
输入: prices = [1]
输出: 0
1
2
2
提示:
1 <= prices.length <= 5000
0 <= prices[i] <= 1000
# Solution
Language: JavaScript
状态
dp[i][0] 表示第 i 天 没有持有 股票得最大利润
dp[i][1] 表示第 i 天 持有 股票时得最大利润
状态转移方程
今天没有:可由下面两种情况转化而来
昨天出售,今天不可以买
昨天持有,今天卖出
dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i]);
今天持有:可由下面两种情况转化而来:
昨天就持有,今天没卖
前天卖出,今天购入
dp[i][1] = max(dp[i-1][1], dp[i-2][0] - prices[i]);
这里 i-2 是因为有冷冻期,前一天不能买,只能在 i-2 那天卖出,然后才可以买
初始状态
dp[0][0] = 0;
dp[0][1] = -price[0];
/**
* @param {number[]} prices
* @return {number}
*/
// let dp = Array.from(new Array(n), () => new Array(2));
var maxProfit = function(prices) {
let len = prices.length;
let dp = [];
let i;
if (prices.length <= 1) {
return 0;
}
for (i = 0; i < len; i++) {
dp[i] = [];
}
dp[0][0] = 0;
dp[0][1] = -prices[0];
dp[1][0] = Math.max(prices[1]-prices[0], 0);
dp[1][1] = Math.max(dp[0][1], dp[0][0]-prices[1]);
for (let i = 2; i < len; i++) {
dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1] + prices[i]);
dp[i][1] = Math.max(dp[i-1][1], dp[i-2][0] - prices[i]);
}
return dp[len-1][0];
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var maxProfit = function(prices) {
let dp = [], n = prices.length;
if (n === 0) return 0;
for (let i = -1; i < n; i++) dp[i] = [];
dp[0][0] = 0;
dp[0][1] = -prices[0];
dp[-1][0] = 0;
for (let i = 1; i < n; i++) {
dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1] + prices[i]);
dp[i][1] = Math.max(dp[i-1][1], dp[i-2][0] - prices[i]);
}
return dp[n-1][0];
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
*
* [309] 最佳买卖股票时机含冷冻期
*/
/**
* @param {number[]} prices
* @return {number}
dp[最后一天][持有/未持有] = ?
[买入,卖出,冷冻期,买入,卖出] 满足最大利润条件下,尽可能地完成更多的交易
dp[3][0] = dp[2][1] dp[2][0] // 这两个不用考虑 dp[1][1] dp[1][0]
dp[3][0] = Math.max(dp[2][1] + prices[3], dp[2][0]);
dp[3][1] = dp[2][1] dp[1][0] // 冷冻期 dp[2][0] 不需要考虑 dp[1][1]
dp[3][1] = Math.max(dp[2][1], dp[1][0] - prices[3])
(64 ms)
*/
var maxProfit = function(prices) {
const n = prices.length;
const dp = new Array(n).fill(0).map(() => new Array(2).fill(0));
// -1天需要的参数
dp[-1] = [0];
dp[0] = [0, -prices[0]];
// 从第一天开始
for(let i = 1; i < n; i++) {
dp[i][0] = Math.max(dp[i-1][1] + prices[i], dp[i-1][0]);
dp[i][1] = Math.max(dp[i-1][1], dp[i-2][0] - prices[i]);
}
// 返回最后一天不持有股票
return dp[n-1][0]
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34