题意
给定一个股票的价格序列,你可以进行最多2次交易,在一天选择买入并在之后的某一天卖出,求能获得的最大利润。
思路
状态表示:
d[i][j][k]
,我们第i天,(j == 0表示未持股),(j == 1表示持股),进行第k次交易的最大利润(当我们买入一只股票的时候认为开始了一次交易)
转移方程:
d[i][0][k]=max(d[i−1][0][k],d[i−1][1][k]+a[i])
d[i][1][k]=max(d[i−1][1][k],(k>0?d[i−1][0][k−1]:0)−a[i])
细节
开始一直wa,有个边界情况没有考虑到就是k == 0的时候(代表我们现在并没有进行任何一次交易),此时持股一定是非法的。
代码
const int maxn = 100005;
const int INF = 0x3e3e3e3e;
int d[maxn][2][3];
class Solution {
public:
int maxProfit(vector<int>& a) {
int n = a.size();
if (n <= 1) return 0;
d[0][0][0] = 0, d[0][0][1] = -INF, d[0][0][2] = -INF;
d[0][1][0] = -INF, d[0][1][1] = -a[0], d[0][1][2] = -INF;
for (int i = 1; i < n; i++) {
for (int k = 0; k <= 2; k++) {
if (k == 0) {
d[i][0][k] = 0;
d[i][1][k] = -INF;
continue;
}
d[i][0][k] = max(d[i - 1][0][k], d[i - 1][1][k] + a[i]);
d[i][1][k] = max(d[i - 1][1][k], (k > 0 ? d[i - 1][0][k - 1] : 0) - a[i]);
}
}
return max(d[n - 1][0][0], max(d[n - 1][0][1], d[n - 1][0][2]));
}
};