动态规划练习题

此文会不定期更新

购买股票问题

LeetCode714.买卖股票的最佳时机含手续费

给定一个整数数组 prices,其中第 i 个元素代表了第 i 天的股票价格 ;非负整数 fee 代表了交易股票的手续费用。

你可以无限次地完成交易,但是你每笔交易都需要付手续费。如果你已经购买了一个股票,在卖出它之前你就不能再继续购买股票了。

返回获得利润的最大值。

注意:这里的一笔交易指买入持有并卖出股票的整个过程,每笔交易你只需要为支付一次手续费。

输入: prices = [1, 3, 2, 8, 4, 9], fee = 2
输出: 8

  • 0 < prices.length <= 50000.
  • 0 < prices[i] < 50000.
  • 0 <= fee < 50000.

dp[i][0] 表示第 i 天未持有股票的最大利润,dp[i][1] 表示第 i天持有股票的最大利润。

那么对于 dp[i][0] ,它的来源有两种:第一种是在第 i - 1 天时手中就没有股票,到了第 i 天仍然没有;第二种是在第 i - 1 天手中有股票,到了第 i 天就卖出了。因此得到递推关系式:

dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i] - fee)

对于 dp[i][1] ,它的来源也有两种:第一种是在第 i - 1 天手中就有股票,第 i 天也没有抛售出去;第二种是在第 i - 1 天未持有股票,在第 i 天购入。递推关系式为:

dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i])

初始条件为:

dp[0][0] = 0 :第 0 天什么也没买

dp[0][1] = -prices[0] :第 0 天买了,那么就只可能买 prices[0] 的股票。

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution {
public:
int maxProfit(vector<int>& prices, int fee) {
int dp[50010][2];
dp[0][0] = 0, dp[0][1] = -prices[0];
int n = prices.size();
for(int i = 0; i < n; i++) {
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i] - fee);
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
}
return max(dp[n - 1][0], dp[n - 1][1]);
}
};

LeetCode188.买卖股票的最佳时机

1
2
3
4
5
6
class Solution {
public:
int maxProfit(int k, vector<int>& prices) {

}
}