题解 | #牛群买卖计划#

牛群买卖计划

https://www.nowcoder.com/practice/3e4ae511b4a941b788da5077b08a7d07

知识点:

动态规划/状态机模型

分析:

dp大家都做了好几百遍了,主要分析状态机模型。

比DP更好理解。

首先上图是一个状态转移图,其次再记住买入和卖出算一次买卖

现在分析状态:

状态表示:

f[i][j][k], k取0或1,0表示手中无货,1表示手中有货,

  • f[i][j][0]:第i天,已经进行完j次交易后的最大利润
  • f[i][j][1]:第i天,正在进行第j次交易(已经进行了j - 1次交易)后的最大利润

一开始从手中无货开始,首先可以转移到手中有货状态,或者是手中无货状态。同理手中有货也有两种状态转移。

手中无货—>手中无货,则f[i][j][0] = f[i-1][j][0],直接等于前一天

手中有货-->手中无货,则f[i][j][0] = f[i-1][j][1] + prices[i], 第i-1天,正在进行第j次交易后的最大利润

f[i][j][0] = max(f[i - 1][j][0], f[i - 1][j][1] + prices[i])

手中有货-->手中有货,则 f[i][j][1] = f[i-1][j][1]

手中无货-->手中有货,则f[i][j][1] = f[i-1][j-1][0] - prices[i] ,这里为什么是j-1呢,是因为进行第j次交易的时候,已经进行了j-1次交易,并且今天再做交易。

f[i][j][1] = max(f[i - 1[j][1], f[i - 1][j - 1][0] - prices[i])

因为都要得到最大利润,所以是都取了max

编程语言:

C++

完整代码:

k = 3

0 <= prices.length <= 10000

    static const int N = 110;
    int f[N][110][2];
    int maxProfit(vector<int>& prices) {
        memset(f, -0x3f, sizeof f);
        for(int i = 0;i<=prices.size();i++) f[i][0][0] = 0;
        for(int i =1;i<=prices.size();i++){
            for(int j = 1;j<=3;j++){
                //0->0 1->0
                f[i][j][0] = max(f[i-1][j][0],f[i-1][j][1] + prices[i - 1]);
                //1->1 0->1
                f[i][j][1] = max(f[i-1][j][1],f[i-1][j-1][0] -prices[i-1]);
            }
        }
        int res = 0;
        for (int i = 0; i <= 3; i ++ ) res = max(res, f[prices.size()][i][0]);
        return res;
    }

全部评论

相关推荐

牛客nb666号:看数据范围, -1e4~1e4, 用一个计数数组存一下, 再按个数让k减到0就行; 堆排不是O(n)的, 快速选择算法是O(n)但随机性较强
点赞 评论 收藏
分享
ALEX_BLX:虾皮好像去年秋招就很抽象,根本不知道要人的标准是啥,而且即使hr面完了也有可能泡不出来池子
投递深圳虾皮信息科技有限公司等公司10个岗位
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务