题目描述
给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。(可以只交易一次或者不交易)
输入: [3,3,5,0,0,3,1,4]
输出: 6
解释: 在第 4 天(股票价格 = 0)的时候买入,在第 6 天(股票价格 = 3)的时候卖出,这笔交易所能获得利润 = 3-0 = 3 。
随后,在第 7 天(股票价格 = 1)的时候买入,在第 8 天 (股票价格 = 4)的时候卖出,这笔交易所能获得利润 = 4-1 = 3 。
解题思路
一个通用方法团灭 6 道股票问题。我的实现。
参考代码
// 原始的动态转移方程,没有可化简的地方
// dp[i][k][0] = max(dp[i-1][k][0], dp[i-1][k][1] + prices[i])
// dp[i][k][1] = max(dp[i-1][k][1], dp[i-1][k-1][0] - prices[i])
// 还记得前面总结的「穷举框架」吗?就是说我们必须穷举所有状态。
// 其实我们之前的解法,都在穷举所有状态,只是之前的题目中 k 都被化简掉了。
// 这道题由于没有消掉 k 的影响,所以必须要对 k 进行穷举:
class Solution {
public:
int maxProfit(vector<int>& prices) {
int length = prices.size();
if(length <= 1)
return 0;
int dp[length][3][2] = {0};
for (int i = 0; i < length; i++)
for (int k = 1; k <= 2; k++) {
if (i - 1 == -1) { // 必须这样处理basecase
/* 处理 base case */
dp[i][k][0] = 0;
dp[i][k][1] = -prices[i];
continue;
}
dp[i][k][0] = max(dp[i-1][k][0], dp[i-1][k][1] + prices[i]);
dp[i][k][1] = max(dp[i-1][k][1], dp[i-1][k-1][0] - prices[i]);
}
return dp[length - 1][2][0];
}
};