題目
題目大意:給一個非負數組,每個元素代表股票當天價格,每次出售股票需要付出固定的小費,求多次購入與出售股票後最終得到的最大利益。
注意:再次購買之前必須先出售股票,即不能同時擁有兩支股票
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];
}
};