本文最后更新于 426 天前,其中的信息可能已经有所发展或是发生改变。
题目描述
- 给定一个整数数组
prices,其中第prices[i]表示第i天的股票价格 。 - 设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):
- 卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。
注意: 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
示例1:
输入: prices = [1, 2, 3, 0, 2]
输出: 3
解释: 对应的交易状态为: [买入, 卖出, 冷冻期, 买入, 卖出]
示例2:
输入: prices = [1]
输出: 0
提示:
- 1 <= prices.length <= 5000
- 0 <= prices[i] <= 1000
解题思路
- 确定dp数组以及下标的含义
dp[i][j] 表示第i天j状态下股票所得的最多现金
dp[i][0]:持有股票的状态- 第i天买入
- 第i-1天持有,第i天不操作, 保持持有状态
dp[i][1]:保持卖出股票的状态- 冷冻期后的1天或n天
dp[i][2]:实际卖出股票的状态,特指在第i天卖出股票 → 下一天为冷冻期dp[i][3]:冷冻期的状态
- 递推公式
dp[i][0]:持有股票第i天买入:看前一天状态
- 前一天为冷冻期:
dp[i][0] = dp[i-1][3] - prices[i] - 前一天为保持卖出状态:
dp[i][0] = dp[i-1][1] - prices[i]
- 前一天为冷冻期:
第i-1天持有:
dp[i][0] = dp[i-1][0]dp[i][0] = max(dp[i-1][3] - prices[i], dp[i-1][1] - prices[i], dp[i-1][0])
dp[i][1]:保持卖出股票状态- 第i-1天保持卖出股票状态:
dp[i][1] = dp[i-1][1] - 第i-1天保冷冻期状态:
dp[i][1] = dp[i-1][3]dp[i][1] = max(dp[i-1][1], dp[i-1][3])
- 第i-1天保持卖出股票状态:
dp[i][2]:实际卖出股票,前一天持有, 后一天冷冻期dp[i][2] = dp[i-1][0] + prices[i]dp[i][3]: 冷冻期,前一天必须卖出股票dp[i][3] = dp[i - 1][2]
- dp数组初始化
dp[0][0] = -prices[0]dp[0][1] = 0:根据递推公式来初始化dp[0][2] = 0:同上dp[0][3] = 0:第一天冷冻期,根据递推公式初始化为0
- 确定遍历顺序 根据递推公式可以看出,
- 打印dp数组
dp[i] 都是由 dp[i-1] 推出来的,那么遍历顺序一定是从前往后遍历
代码实现
- 核心模式
class Solution{
public:
int maxProfit(vector<int>& prices){
int len = prices.size();
if (len == 0) return 0;
vector<vector<int>> dp(len, vector<int>(4, 0));
//initialize the DP array
dp[0][0] = -prices[0];
for (int i = 1; i < len; i++){
dp[i][0] = max(dp[i - 1][3] - prices[i], max(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];
}
// The maxProfit may appear in state1, state2 and state3
return max(dp[len - 1][1], max(dp[len - 1][2], dp[len - 1][3]));
}
};
- ACM模式 "dynamicPro.h"
#include <iostream>
#include "dynamicPro.h"
class Solution{
public:
int maxProfit(const vector<int>& prices){
using std::max;
int len = prices.size();
if (len == 0) return 0;
vector<vector<int>> dp(len, vector<int>(4, 0));
//initialize the DP array
dp[0][0] = -prices[0];
for (int i = 1; i < len; i++){
dp[i][0] = max(dp[i - 1][3] - prices[i], max(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];
}
print2DVector(dp);
// The maxProfit may appear in state1, state2 and state3
return max(dp[len - 1][1], max(dp[len - 1][2], dp[len - 1][3]));
}
};
int main(){
vector<int> case1 = {1, 2, 3, 0, 2};
vector<int> case2 = {1};
Solution solution;
cout << "Result1's DP array = " << solution.maxProfit(case1) << endl;
cout << "Result2's DP array = " << solution.maxProfit(case2) << endl;
}
- 输出
Result1's DP array = [[-1, 0, 0, 0], [-1, 0, 1, 0], [-1, 0, 2, 1], [1, 1, -1, 2], [1, 2, 3, -1]]
3
Result2's DP array = [[-1, 0, 0, 0]]
0