股票最大利润4

给你一个整数数组 prices 和一个整数 k ,其中 prices[i] 是某支给定的股票在第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。也就是说,你最多可以买 k 次,卖 k 次。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

示例 1:

输入:k = 2, prices = [2,4,1]
输出:2
解释:在第 1 天 (股票价格 = 2) 的时候买入,在第 2 天 (股票价格 = 4) 的时候卖出,这笔交易所能获得利润 = 4-2 = 2 。

示例 2:

输入:k = 2, prices = [3,2,6,5,0,3]
输出:7
解释:在第 2 天 (股票价格 = 2) 的时候买入,在第 3 天 (股票价格 = 6) 的时候卖出, 这笔交易所能获得利润 = 6-2 = 4 。
     随后,在第 5 天 (股票价格 = 0) 的时候买入,在第 6 天 (股票价格 = 3) 的时候卖出, 这笔交易所能获得利润 = 3-0 = 3 。

提示:

  • 1 <= k <= 100
  • 1 <= prices.length <= 1000
  • 0 <= prices[i] <= 1000


class Solution {
public:
    int maxProfit(int k, vector<int>& prices) {
        int n = prices.size();

        vector<vector<int>> dp(k + 1, vector<int>(n, 0));

        for (int t = 1; t <= k; ++t) {
            int max_diff = -prices[0];  // 初始化最大差值
            for (int i = 1; i < n; ++i) {
                dp[t][i] = max(dp[t][i - 1], prices[i] + max_diff);
                max_diff = max(max_diff, dp[t - 1][i] - prices[i]);
            }
        }

        return dp[k][n - 1];  // 返回最多 k 笔交易的最大利润
    }
};

 vector<vector<int>> dp(k + 1, vector<int>(n, 0));k + 1 是该数组的第一维大小,表示从 0 次交易到最多 k 次交易,因此共有 k + 1 行。

 dp[t][i] 表示最多进行 t 笔交易并且在第 i 天结束时能获取的最大利润

对于每一笔交易 t,我们遍历每一天 i,尝试计算出在第 i 天最多进行 t 次交易的最大利润。

  • dp[t][i] = max(dp[t][i-1], prices[i] + max_diff)
    • dp[t][i-1] 表示在不进行交易的情况下,最大利润为前一天的利润。
    • prices[i] + max_diff 表示在第 i 天卖出股票所获得的最大利润。
  • max_diff = max(max_diff, dp[t-1][i] - prices[i])
    • dp[t-1][i] - prices[i] 表示在第 i 天之前最多进行 t-1 笔交易的最大利润,减去第 i 天买入股票的价格。这帮助我们在后续天数计算中寻找最佳的买入点。

假设:prices = [3, 2, 6, 5, 0, 3]k = 2

第 1 笔交易时 (t = 1):

初始化 max_diff = -prices[0] = -3,表示第 0 天买入的代价。

  • 第 1 天 (i = 1):

    • dp[1][1] = max(dp[1][0], prices[1] + max_diff)
    • dp[1][1] = max(0, 2 + (-3)) = 0
    • 更新 max_diff: max_diff = max(-3, dp[0][1] - prices[1]) = max(-3, 0 - 2) = -2
  • 第 2 天 (i = 2):

    • dp[1][2] = max(dp[1][1], prices[2] + max_diff)
    • dp[1][2] = max(0, 6 + (-2)) = 4(第 1 天买入,第 2 天卖出)
    • 更新 max_diff: max_diff = max(-2, dp[0][2] - prices[2]) = max(-2, 0 - 6) = -2(保持不变)
  • 第 3 天 (i = 3):

    • dp[1][3] = max(dp[1][2], prices[3] + max_diff)
    • dp[1][3] = max(4, 5 + (-2)) = 4(不交易,维持第 2 天的利润)
    • 更新 max_diff: max_diff = max(-2, dp[0][3] - prices[3]) = max(-2, 0 - 5) = -2
  • 第 4 天 (i = 4):

    • dp[1][4] = max(dp[1][3], prices[4] + max_diff)
    • dp[1][4] = max(4, 0 + (-2)) = 4
    • 更新 max_diff: max_diff = max(-2, dp[0][4] - prices[4]) = max(-2, 0 - 0) = 0
  • 第 5 天 (i = 5):

    • dp[1][5] = max(dp[1][4], prices[5] + max_diff)
    • dp[1][5] = max(4, 3 + 0) = 4
    • 更新 max_diff: max_diff = max(0, dp[0][5] - prices[5]) = max(0, 0 - 3) = 0
第一笔交易完成,dp[1][n-1] = dp[1][5] = 4,意味着在最多进行 1 笔交易的情况下,最大利润是 4。

第 2 笔交易时 (t = 2):

初始化 max_diff = -prices[0] = -3

  • 第 1 天 (i = 1):

    • dp[2][1] = max(dp[2][0], prices[1] + max_diff)
    • dp[2][1] = max(0, 2 + (-3)) = 0
    • 更新 max_diff: max_diff = max(-3, dp[1][1] - prices[1]) = max(-3, 0 - 2) = -2
  • 第 2 天 (i = 2):

    • dp[2][2] = max(dp[2][1], prices[2] + max_diff)
    • dp[2][2] = max(0, 6 + (-2)) = 4
    • 更新 max_diff: max_diff = max(-2, dp[1][2] - prices[2]) = max(-2, 4 - 6) = -2
  • 第 3 天 (i = 3):

    • dp[2][3] = max(dp[2][2], prices[3] + max_diff)
    • dp[2][3] = max(4, 5 + (-2)) = 4
    • 更新 max_diff: max_diff = max(-2, dp[1][3] - prices[3]) = max(-2, 4 - 5) = -1
  • 第 4 天 (i = 4):

    • dp[2][4] = max(dp[2][3], prices[4] + max_diff)
    • dp[2][4] = max(4, 0 + (-1)) = 4
    • 更新 max_diff: max_diff = max(-1, dp[1][4] - prices[4]) = max(-1, 4 - 0) = 4
  • 第 5 天 (i = 5):

    • dp[2][5] = max(dp[2][4], prices[5] + max_diff)
    • dp[2][5] = max(4, 3 + 4) = 7
    • 更新 max_diff: max_diff = max(4, dp[1][5] - prices[5]) = max(4, 4 - 3) = 4
第二笔交易完成,dp[2][n-1] = dp[2][5] = 7,意味着在最多进行 2 笔交易的情况下,最大利润是 7。

方法二:


class Solution {
public:
    int maxProfit(int k, vector<int>& prices) {

        vector<int> buy(k + 1, INT_MIN);
        vector<int> sell(k + 1, 0);

        for (int price : prices) {
            for (int j = 1; j <= k; ++j) {
                buy[j] = max(buy[j], sell[j - 1] - price); // 买入操作
                sell[j] = max(sell[j], buy[j] + price);    // 卖出操作
            }
        }

        return sell[k]; // 最终返回最大利润
    }
};

vector<int> buy(k + 1, INT_MIN); 

初始状态下的利润设置为极小值。这是因为在一开始我们还没有进行任何买入操作,初始状态下假设买入的利润极低(也就是不可能)。

  • buy[j]:表示最多进行 j 笔交易后,当前手上持有股票时的最大利润
  • sell[j]:表示最多进行 j 笔交易后,当前手上不持有股票时的最大利润

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值