题目
分析
这题是我很少做过的dp,和之前那个树的最小和问题有点像,因为它是有多个状态交错依赖的。这题中有四个行为:
- 没有股票的情况下:买股票
- 没有股票的情况下:什么也不做
- 有股票的情况下:卖股票
- 有股票的情况下:什么也不做
它特殊的地方就在于不止有买卖这两种操作,还有有没有股票的持有与否。所以比较明确的思路就需要四个数组。当然,这在之后可以进行优化。然后的思路就很简单了
你要买,就必须之前没有股票
要卖,必须之前有股票
这都是非常显然的。在代码中有详细注释
时间复杂度分析
时间复杂度是遍历一次的复杂度,为O(n),这可已经是最小的了,但是可以控制数组的个数。
代码
首先放出一个非常好理解的版本
class Solution{
public:
int maxProfit(vector<int> &prices, int fee) {
// buy a stock on day i
vector<int> buy(prices.size(), 0);
// sell a stock on day i
vector<int> sell(prices.size(), 0);
// we don't have a stock and do nothing on day i
vector<int> notHold(prices.size(), 0);
// we have a stock and do nothing on day i
vector<int> hold(prices.size(), 0);
buy[0] = hold[0] = 0- prices[0];
for (int i = 1; i < prices.size(); i++) {
// we can buy a stock only if we don't have a stock on day i-1
buy[i] = max(sell[i-1], notHold[i-1]) - prices[i];
// we can sell a stock only if we have a stock on day i-1
sell[i] = max(hold[i-1], buy[i-1]) + prices[i] - fee;
// we can hold a stock only if we have a stock on day i-1
hold[i] = max(hold[i-1], buy[i-1]);
// we can notHold a stock only if we don't have a stock on day i
notHold[i] = max(notHold[i-1], sell[i-1]);
}
int ans = max(buy[prices.size() - 1], sell[prices.size() - 1]);
int ans2 = max(notHold[prices.size() - 1], hold[prices.size() - 1]);
return max(ans, ans2);
}
};
简单的观察后,就可以进行优化
class Solution{
public:
int maxProfit(vector<int> &prices, int fee) {
// buy a stock on day i
int buy = 0 - prices[0];
// sell a stock on day i
int sell = 0;
// we don't have a stock and do nothing on day i
int notHold = 0;
// we have a stock and do nothing on day i
int hold = 0 - prices[0];
for (int i = 1; i < prices.size(); i++) {
// we can notHold a stock only if we don't have a stock on day i
notHold = max(notHold, sell);
// we can hold a stock only if we have a stock on day i-1
hold = max(hold, buy);
// we can buy a stock only if we don't have a stock on day i-1
buy = notHold - prices[i];
// we can sell a stock only if we have a stock on day i-1
sell = hold + prices[i] - fee;
}
int ans = max(buy, sell);
int ans2 = max(notHold, hold);
return max(ans, ans2);
}
};
当然,可以有更多优化,但是这种思路比较清楚,因此就只放出这两个。