leetcode-188. 买卖股票的最佳时机 IV

股票交易问题(动态规划)


题目详情

给定一个整数数组 prices ,它的第 i 个元素 prices[i] 是一支给定的股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 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 * 2 >= days 我们买入卖出需要至少两天时间,所以如果是这种情况,我们直接利用贪心即可,一有利润就卖出,这样所求得的总利润最大
2.若k * 2 < days 在这种情况下,情况相对复杂,我们可以利用两个dp数组buy sell,buy[j]用来记录在第j次买入的最大利润,sell[j]用来记录在第j次卖出的最大利润

我的代码:

class Solution 
{
public:
    //辅函数(买入后有利润就卖出---贪心)
    int maxProfitUnlimited(vector<int> prices)
    {
        int maxProfit = 0;
        for (int i = 1; i < prices.size(); ++i)
        {
            if (prices[i] > prices[i-1])
            maxProfit += prices[i] - prices[i-1];
        }
        return maxProfit;
    }
    //主函数
    int maxProfit(int k, vector<int>& prices) 
    {
        int days = prices.size();
        if (days < 2) return 0;

        if (k * 2 >= days)   //情况一直接贪心
        return maxProfitUnlimited(prices);

        vector<int> buy(k + 1, INT_MIN), sell(k + 1, 0);
        //遍历每天的股票价格
        for (int i = 0; i < days; ++i)
        {
            //该天的股票以第j次买入卖出
            for (int j = 1; j <= k; ++j)
            {
                //更新(分析第j次是买入还是卖出)
        /* 为了求buy[j](作为第j次是/否买入的最大利润,说明j-1次是卖出的,本次我们只能选择不操作或者买入)
        括号里的buy[j]的意思是没有将该天的股票作为第j次买入(第j次买入的是其他的股票),即不操作
        如果该天确定买入,此时手里的钱是sell[j-1](第j-1次卖出过的最佳状态) - prices[i](买入价格)
        */
                buy[j] = max(buy[j], sell[j-1] - prices[i]);
        /*为了求sell[j](作为第j次是/否卖出的最大利润,说明j-1次是买入的,本次我们选择不操作或者卖出)
        同理括号里的sell[j]的意思是不操作
        如果该天确定卖出,此时手里的钱是buy[j](第j次买入的最佳状态) + prices[i](卖出价格)
        */          
                sell[j] = max(sell[j], buy[j] + prices[i]);
            }
        }
        return sell[k];
    }
};

本题我迷糊的点是:
for循环里,为什么更新buy数组括号里是sell[j-1]
而更新sell数组括号里是buy[j]而不是buy[j-1]
太傻了,因为buy和sell是一一对应的,只有对应的下标(次)先买入,才能卖出
只有存在了buy[j],才能取用sell[j]

涉及知识点:

1.动态规划(dp)

动态规划

posted @ 2022-07-10 11:42  ggaoda  阅读(6)  评论(0编辑  收藏  举报  来源