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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
| //
struct Solution;
// @lc code=start
use std::cmp;
impl Solution {
/// ## 解题思路:
/// - 动态规划+贪心
/// 1. 设 profit[i]: 投资者从第i天开始到最后的最终投资收益;
/// 2. 投资者每天存在2种状态:
/// - 未投资(uninvested):
/// - 已投资(invested);
/// 3. 投资者每天可以有不同投资策略, 以获得最大利润:
/// - 未投资(uninvested), 此时有两种投资策略:
/// - 不操作. 此时当天投资收益为0, 后续投资收益为: profit[i+1].未投资;
/// - 买入. 此时当天投资收益为: -prices[i], 后续投资收益为: profit[i+1].已投资;
/// 最大收益为: max(0+profit[i+1].未投资, profit[i+1].已投资 - prices[i])
/// - 已投资(invested), 此时也有2总策略:
/// - 不操作. 此时当天投资收益为: 0, 后续投资收益为: profit[i+1].已投资;
/// - 卖出. 此时当天投资收益为: prices[i]. 后续投资收益为: profit[i+1].未投资
/// 最大收益为: max(profit[i+1].已投资, profit[i+1].未投资 + prices[i])
/// 4. 最终最大收益为: profit[0].未投资
/// 初始条件: profit[n]: (0, 0)
pub fn max_profit(prices: Vec<i32>) -> i32 {
let K = 2;
let n = prices.len();
let mut profit = vec![(0, 0); K + 1];
for &p in prices.iter().rev() {
for k in 1..=K {
profit[k].0 = profit[k].0.max(-p + profit[k].1);
profit[k].1 = profit[k].1.max(p + profit[k - 1].0);
}
}
profit[K].0
}
/// ## 解题思路:
/// 第i天,共有5种操作:
/// 1. 无操作;
/// 2. 第1次买入;
/// 3. 第1次卖出;
/// 4. 第2次买入;
/// 5. 第2次卖出;
///
/// 其中第1种操作不会产生任何利润,后面4次操作最大利润递推公式分别如下:
/// 1. buy1(i) = max(buy1(i-1), -prices[i]), 注意: buy1(i-1):表示[0, i-1]执行了一次买入操作的最大利润, 则第i天将不执行买入操作;-prices[i]表示第i天执行买入操作,所以利润为负;
/// 2. sell1(i) = max(sell1(i-1), buy1(i-1)+prices[i]), 第i天第1次卖出操作的最大利润为:不操作,此时最大利润为前一天第一次卖出最大利润或第一次卖出,最大利润和
/// 3. buy2(i) = max(buy2(i-1), sell1(i-1)-prices[i])
/// 3. sell2(i) = max(sell2(i-1), buy2(i-1)+prices[i])
pub fn max_profit2(prices: Vec<i32>) -> i32 {
if prices.len() < 2 {
return 0 as i32;
}
let mut buy1 = 0 - prices[0]; // 第一次买入后的收益(第一次买入前手中没有股票, 也没有参与过买卖,)
let mut sell1 = 0; // 第一次卖出后的收益(卖出前手中的股票为0)
let mut buy2 = -prices[0]; // 第二次买入后的收益
let mut sell2 = 0; // 第二次卖出后的收益
for i in 1..prices.len() {
buy1 = cmp::max(buy1, -prices[i]);
sell1 = cmp::max(sell1, buy1 + prices[i]);
buy2 = cmp::max(buy2, sell1 - prices[i]);
sell2 = cmp::max(sell2, buy2 + prices[i]);
}
sell2
}
}
// @lc code=end
|