题目
题目大意:给一个非负数组,每个元素代表股票当天价格,每次出售股票需要付出固定的小费,求多次购入与出售股票后最终得到的最大利益。
注意:再次购买之前必须先出售股票,即不能同时拥有两支股票
Example 1:
Input: prices = [1, 3, 2, 8, 4, 9], fee = 2
Output: 8
Explanation: The maximum profit can be achieved by:
Buying at prices[0] = 1
Selling at prices[3] = 8
Buying at prices[4] = 4
Selling at prices[5] = 9
The total profit is ((8 - 1) - 2) + ((9 - 4) - 2) = 8.
思路
每天要么持有股票、要么没有股票,而每天的状态是由前一天迁移过来的,最后股票一定会被出售。
定义状态
unhold[i] : 第i天不持有股票时,前i天最大利润
hold[i] : 第i天持有股票时,前i天最大利润
注意:
第0天,持有股票的利润为 -prices[0]
数组hold只是辅助状态,最终股票一定被售出,所以最大利润为 unhold[n - 1]
状态迁移
从上图可以看到,
如果今天的状态是没有股票(unhold),那么
①要么是保留了前一天没有股票的状态
②要么是前一天有股票但是今天卖出了
这样我们就能从①②取最大利润作为今天unhold时的目前最大利润。
数组hold的迭代同理。
转移方程
unhold[i] = max(unhold[i - 1], hold[i - 1] + prices[i] - fee)
hold[i] = max(hold[i - 1], unhold[i - 1] - prices[i])
代码
class Solution {
public:
int maxProfit(vector<int>& prices, int fee) {
int n = prices.size();
if (n <= 1) return 0;
vector<int> hold(n, 0), unhold(n, 0);
hold[0] = -prices[0];
for (int i = 1; i < n; i++) {
unhold[i] = max(unhold[i - 1], hold[i - 1] + prices[i] - fee);
hold[i] = max(hold[i - 1], unhold[i - 1] - prices[i]);
}
return unhold[n - 1];
}
};