跳转至

3652. 按策略买卖股票的最佳时机

题目描述

给你两个整数数组 pricesstrategy,其中:

  • prices[i] 表示第 i 天某股票的价格。
  • strategy[i] 表示第 i 天的交易策略,其中:
    • -1 表示买入一单位股票。
    • 0 表示持有股票。
    • 1 表示卖出一单位股票。

同时给你一个 偶数 整数 k,你可以对 strategy 进行 最多一次 修改。一次修改包括:

  • 选择 strategy 中恰好 k 个 连续 元素。
  • 将前 k / 2 个元素设为 0(持有)。
  • 将后 k / 2 个元素设为 1(卖出)。

利润 定义为所有天数中 strategy[i] * prices[i] 的 总和 

返回你可以获得的 最大 可能利润。

注意: 没有预算或股票持有数量的限制,因此所有买入和卖出操作均可行,无需考虑过去的操作。

 

示例 1:

输入: prices = [4,2,8], strategy = [-1,0,1], k = 2

输出: 10

解释:

修改 策略 利润计算 利润
原始 [-1, 0, 1] (-1 × 4) + (0 × 2) + (1 × 8) = -4 + 0 + 8 4
修改 [0, 1] [0, 1, 1] (0 × 4) + (1 × 2) + (1 × 8) = 0 + 2 + 8 10
修改 [1, 2] [-1, 0, 1] (-1 × 4) + (0 × 2) + (1 × 8) = -4 + 0 + 8 4

因此,最大可能利润是 10,通过修改子数组 [0, 1] 实现。

示例 2:

输入: prices = [5,4,3], strategy = [1,1,0], k = 2

输出: 9

解释:

修改 策略 利润计算 利润
原始 [1, 1, 0] (1 × 5) + (1 × 4) + (0 × 3) = 5 + 4 + 0 9
修改 [0, 1] [0, 1, 0] (0 × 5) + (1 × 4) + (0 × 3) = 0 + 4 + 0 4
修改 [1, 2] [1, 0, 1] (1 × 5) + (0 × 4) + (1 × 3) = 5 + 0 + 3 8

因此,最大可能利润是 9,无需任何修改即可达成。

 

提示:

  • 2 <= prices.length == strategy.length <= 105
  • 1 <= prices[i] <= 105
  • -1 <= strategy[i] <= 1
  • 2 <= k <= prices.length
  • k 是偶数

解法

方法一:前缀和 + 枚举

我们用一个数组 \(\textit{s}\) 来表示前缀和,其中 \(\textit{s}[i]\) 表示前 \(i\) 天的利润和,即 \(\textit{s}[i] = \sum_{j=0}^{i-1} \textit{prices}[j] \times \textit{strategy}[j]\)。我们还用一个数组 \(\textit{t}\) 来表示前缀和,其中 \(\textit{t}[i]\) 表示前 \(i\) 天的股票价格和,即 \(\textit{t}[i] = \sum_{j=0}^{i-1} \textit{prices}[j]\)

初始时,最大利润为 \(\textit{s}[n]\)。我们枚举修改的子数组的右端点 \(i\),则左端点为 \(i-k\)。修改后,子数组内前 \(k/2\) 天的策略变为 \(0\),后 \(k/2\) 天的策略变为 \(1\),因此利润变化为:

\[\Delta = -(\textit{s}[i] - \textit{s}[i-k]) + (\textit{t}[i] - \textit{t}[i-k/2])\]

因此,我们可以通过枚举所有可能的 \(i\) 来更新最大利润。

时间复杂度 \(O(n)\),空间复杂度 \(O(n)\)。其中 \(n\) 是数组的长度。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class Solution:
    def maxProfit(self, prices: List[int], strategy: List[int], k: int) -> int:
        n = len(prices)
        s = [0] * (n + 1)
        t = [0] * (n + 1)
        for i, (a, b) in enumerate(zip(prices, strategy), 1):
            s[i] = s[i - 1] + a * b
            t[i] = t[i - 1] + a
        ans = s[n]
        for i in range(k, n + 1):
            ans = max(ans, s[n] - (s[i] - s[i - k]) + t[i] - t[i - k // 2])
        return ans
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
class Solution {
    public long maxProfit(int[] prices, int[] strategy, int k) {
        int n = prices.length;
        long[] s = new long[n + 1];
        long[] t = new long[n + 1];
        for (int i = 1; i <= n; i++) {
            int a = prices[i - 1];
            int b = strategy[i - 1];
            s[i] = s[i - 1] + a * b;
            t[i] = t[i - 1] + a;
        }
        long ans = s[n];
        for (int i = k; i <= n; i++) {
            ans = Math.max(ans, s[n] - (s[i] - s[i - k]) + (t[i] - t[i - k / 2]));
        }
        return ans;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
class Solution {
public:
    long long maxProfit(vector<int>& prices, vector<int>& strategy, int k) {
        int n = prices.size();
        vector<long long> s(n + 1), t(n + 1);
        for (int i = 1; i <= n; i++) {
            int a = prices[i - 1];
            int b = strategy[i - 1];
            s[i] = s[i - 1] + a * b;
            t[i] = t[i - 1] + a;
        }
        long long ans = s[n];
        for (int i = k; i <= n; i++) {
            ans = max(ans, s[n] - (s[i] - s[i - k]) + (t[i] - t[i - k / 2]));
        }
        return ans;
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
func maxProfit(prices []int, strategy []int, k int) int64 {
    n := len(prices)
    s := make([]int64, n+1)
    t := make([]int64, n+1)

    for i := 1; i <= n; i++ {
        a := prices[i-1]
        b := strategy[i-1]
        s[i] = s[i-1] + int64(a*b)
        t[i] = t[i-1] + int64(a)
    }

    ans := s[n]
    for i := k; i <= n; i++ {
        ans = max(ans, s[n]-(s[i]-s[i-k])+(t[i]-t[i-k/2]))
    }
    return ans
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
function maxProfit(prices: number[], strategy: number[], k: number): number {
    const n = prices.length;
    const s: number[] = Array(n + 1).fill(0);
    const t: number[] = Array(n + 1).fill(0);

    for (let i = 1; i <= n; i++) {
        const a = prices[i - 1];
        const b = strategy[i - 1];
        s[i] = s[i - 1] + a * b;
        t[i] = t[i - 1] + a;
    }

    let ans = s[n];
    for (let i = k; i <= n; i++) {
        const val = s[n] - (s[i] - s[i - k]) + (t[i] - t[i - Math.floor(k / 2)]);
        ans = Math.max(ans, val);
    }
    return ans;
}

评论