题目
题目链接
解题思路
这道题是股票买卖的进阶版本,最多允许两次交易。我们可以使用动态规划来解决:
- 对于每一天,我们有以下几种状态:
- 第一次买入(\(buy1\))
- 第一次卖出(\(sell1\))
- 第二次买入(\(buy2\))
- 第二次卖出(\(sell2\))
- 对于每个状态,我们都记录到当前天为止的最大收益
- 状态转移方程:
- \(buy1 = max(buy1, -price)\)
- \(sell1 = max(sell1, buy1 + price)\)
- \(buy2 = max(buy2, sell1 - price)\)
- \(sell2 = max(sell2, buy2 + price)\)
代码
#include <iostream>
#include <vector>
#include <climits>
using namespace std;int maxProfit(vector<int>& prices) {int buy1 = INT_MIN, sell1 = 0;int buy2 = INT_MIN, sell2 = 0;for(int price : prices) {buy1 = max(buy1, -price);sell1 = max(sell1, buy1 + price);buy2 = max(buy2, sell1 - price);sell2 = max(sell2, buy2 + price);}return sell2;
}int main() {int n;cin >> n;vector<int> prices(n);for(int i = 0; i < n; i++) {cin >> prices[i];}cout << maxProfit(prices) << endl;return 0;
}
import java.util.Scanner;public class Main {public static int maxProfit(int[] prices) {int buy1 = Integer.MIN_VALUE, sell1 = 0;int buy2 = Integer.MIN_VALUE, sell2 = 0;for(int price : prices) {buy1 = Math.max(buy1, -price);sell1 = Math.max(sell1, buy1 + price);buy2 = Math.max(buy2, sell1 - price);sell2 = Math.max(sell2, buy2 + price);}return sell2;}public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();int[] prices = new int[n];for(int i = 0; i < n; i++) {prices[i] = sc.nextInt();}System.out.println(maxProfit(prices));sc.close();}
}
def max_profit(prices):buy1 = float('-inf')sell1 = 0buy2 = float('-inf')sell2 = 0for price in prices:buy1 = max(buy1, -price)sell1 = max(sell1, buy1 + price)buy2 = max(buy2, sell1 - price)sell2 = max(sell2, buy2 + price)return sell2n = int(input())
prices = list(map(int, input().split()))
print(max_profit(prices))
算法及复杂度
- 算法:动态规划
- 时间复杂度:\(\mathcal{O}(n)\),只需要遍历一次数组
- 空间复杂度:\(\mathcal{O}(1)\),只使用了常数个变量