前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >LeetCode 188. Best Time to Buy and Sell Stock IV (动态规划)

LeetCode 188. Best Time to Buy and Sell Stock IV (动态规划)

作者头像
ShenduCC
发布2020-02-17 11:11:40
3810
发布2020-02-17 11:11:40
举报
文章被收录于专栏:算法修养算法修养

题意:给你一个数组代表每天的股价。你有k次买入和卖出的机会,问你最多能赚多少钱。买入之前必须卖出已有股份。同一天是可以先买,再卖,或者先卖再买的。

题解:题目没有说数据范围,但是经过我实际测试 k 最大为10^8 ,n最大为10^4。当然k最多只需要取n/2就好了,因为当天买当天卖是没有意义的。

那这道题的效率就应该控制在O(n*k),再加一点就要超时了,所以两个循环嵌套。第一层是k,第二层是n

状态数组dp[k][i] 表示开始第k次买卖的交易时,第i天口袋里可以赚到的最多的钱。那么状态转移的思路就是,第i天,这一天我要么什么也不做:dp[i]=d[i-1],要么我把手里的股份在今天卖出,dp[i]=m+prices[i],这里的m是之前某一天我买进了股份,剩下的钱。所以,m应该越大越好。那么m怎么算呢?m = Max { dp[k-1][j] - prices[j] } ( j = 0..i-1) dp[k-1][j] 表示k-1次交易后,在第j天赚的钱。

整个状态转移过程,在k维度上,只需要k和k-1转移,所以,状态数组用两个dp数组就可以了,无需k个。

代码语言:javascript
复制
class Solution {
public:
    int dp[10005];
    int bp[10005];
    int maxProfit(int k, vector<int>& prices) {
        
        if(k==0 || prices.size()<=1)
            return 0;
        
        for(int i=0;i<k&&i<prices.size()/2;i++)
        {
            int m = -99999999;
            for(int j=1;j<prices.size();j++)
            {
                m = max(m,bp[j-1]-prices[j-1]);
                
                dp[j] = max(dp[j-1],m+prices[j]);
            }
            
            for(int j=0;j<prices.size();j++)
            {
                bp[j]=dp[j];
                dp[j]=0;
            }
        }
        
        return bp[prices.size()-1];
        
    }
};
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-02-04 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档