题目描述:
309.最佳买卖股票时机含冷冻期
给定一个整数数组,其中第 i 个元素代表了第 i 天的股票价格 。
设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):
- 你必须在每个交易日结束前,都持有一支股票。
- 卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。
示例:
输入: [1,2,3,0,2] 输出: 3 解释: 对于给定的输入数组, 在第 i 天买入股票, 在第 j 天卖出股票, 利润为 j - i - 1 (注意: 这里的 i 和 j 都是从 0 开始计数的)。
714.买卖股票的最佳时机含手续费
给定一个整数数组 prices,其中第 i 个元素代表了第 i 天的股票价格 ;非负整数 fee 代表了交易股票的手续费用。
你可以无限次地完成交易,但是你每次交易都需要付手续费。如果你已经购买了一个股票,在卖出它之前你就不能再购买股票了。
返回获得利润的最大值。
示例:
输入: prices = [1, 3, 2, 8, 4, 9], fee = 2
输出: 8
解释: 能够达到的最大利润:
在此处买入 prices[0] = 1,在此处卖出 prices[3] = 8,利润 = 8 - 1 - 2 = 5 。
注意利润不能是 7,因为卖出价格需要大于买入价格。
技术报告:
一、最佳买卖股票时机含冷冻期
动态规划是解决这个问题的最佳方法。定义状态转移方程为:
dp[i][0] 表示第 i 天交易完后手里没有股票的最大利润,dp[i][1] 表示第 i 天交易完后手里持有一支股票的最大利润,dp[i][2] 表示第 i 天交易完后手里持有股票,且处于冷冻期的最大利润。
状态转移方程如下:
dp[i][0] = max(dp[i-1][0], dp[i-1][2]) dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i]) dp[i][2] = dp[i-1][1]+prices[i]
其中,dp[i][0] 表示第 i 天不持有股票,有两种情况:一是第 i-1 天也没有股票,dp[i-1][0];二是第 i-1 天持有股票但在第 i 天卖了,即 dp[i-1][2]。
dp[i][1] 表示第 i 天持有股票,有两种情况:一是第 i-1 天也持有股票,dp[i-1][1];二是第 i-1 天没有股票,但在第 i 天买了,即 dp[i-1][0]-prices[i]。
dp[i][2] 表示第 i 天持有股票,且处于冷冻期,只有一种情况:第 i-1 天持有股票,在第 i 天卖出,即 dp[i-1][1]+prices[i]。
最终结果为 dp[n-1][0],即最后一天交易完成后手里没有股票的最大利润。
Java 代码实现:
public int maxProfit(int[] prices) {
if (prices == null || prices.length == 0) {
return 0;
}
int n = prices.length;
int[][] dp = new int[n][3];
dp[0][0] = 0;
dp[0][1] = -prices[0];
dp[0][2] = 0;
for (int i = 1; i < n; i++) {
dp[i][0] = Math.max(dp[i-1][0], dp[i-1][2]);
dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0]-prices[i]);
dp[i][2] = dp[i-1][1]+prices[i];
}
return Math.max(dp[n-1][0], dp[n-1][2]);
}
二、买卖股票的最佳时机含手续费
同样利用动态规划的思想,定义状态转移方程为:
dp[i][0] 表示第 i 天交易完后手里没有股票的最大利润,dp[i][1] 表示第 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])
其中,dp[i][0] 表示第 i 天不持有股票,有两种情况:一是第 i-1 天也没有股票,dp[i-1][0];二是第 i-1 天持有股票但在第 i 天卖了,即 dp[i-1][1]+prices[i]-fee。
dp[i][1] 表示第 i 天持有股票,有两种情况:一是第 i-1 天也持有股票,dp[i-1][1];二是第 i-1 天没有股票,但在第 i 天买了,即 dp[i-1][0]-prices[i]。
最终结果为 dp[n-1][0],即最后一天交易完成后手里没有股票的最大利润。
Java 代码实现:
public int maxProfit(int[] prices, int fee) {
if (prices == null || prices.length == 0) {
return 0;
}
int n = prices.length;
int[][] dp = new int[n][2];
dp[0][0] = 0;
dp[0][1] = -prices[0];
for (int i = 1; i < n; i++) {
dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1]+prices[i]-fee);
dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0]-prices[i]);
}
return dp[n-1][0];
}
以上就是两道题的解法和代码实现,希望能够对大家有所帮助。