zoukankan      html  css  js  c++  java
  • 【dp】leetcode Best Time to Buy and Sell Stock IV

    https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/description/

    【题意】

    给定n天股市的票价,最多交易k次,问最大盈利是多少,手上不能同时持有两支股票。

    【思路】

    考虑加入当天买当天卖这种情况,问题转换为n天总共交易k次(不是最多),因为后一次的买一定在前一次卖之后,所以需要dp[i][j]表示前i天交易j次且最后一次交易在第i天的最大利润。则

    dp[i][j]=max(a[i]-a[k]+global[k-1][j-1]) 1<=k<=i

    k=i表示当天买当天卖,global[i][j]表示max{dp[k][j]} 1<=k<=i

    注意这里是global[k-1][j-1]而不是global[k][j],因为若最后一次交易恰好在第k天,则a[i]-a[k]+global[k][j-1]一共进行j-1次交易,而不是j次。

    dp[i][j]=max(a[i]-a[k]+global[k-1][j-1])(1<=k<=i)

              =max(a[i]-a[i-1]+a[i-1]-a[k]+global[k-1][j-1],global[i-1][j-1])) (1<=k<=i-1)

              =max(a[i]-a[i-1]+dp[i-1][j],global[i-1][j-1]) (1<=k<=i-1)

    【复杂度】

    时间复杂度O(kn),空间可以用滚动数组,为O(1)

    【AC】

     1 class Solution {
     2 public:
     3     int maxProfit(int k, vector<int>& prices) {
     4         int len=prices.size();
     5         if(len==0 || len==1) return 0;
     6         if(k==0) return 0;
     7         if(k>=len/2){
     8             int ans=0;
     9             for(int i=1;i<len;i++){
    10                 ans+=max(0,prices[i]-prices[i-1]);
    11             }
    12             return ans;
    13         }
    14         vector<int> local,global;
    15         local.resize(len);
    16         global.resize(len);
    17         for(int i=0;i<len;i++){
    18             local[i]=global[i]=0;
    19         }
    20         for(int j=1;j<=k;j++){
    21             for(int i=1;i<len;i++){
    22                 local[i]=max(local[i-1]+prices[i]-prices[i-1],global[i-1]);
    23             }
    24             for(int i=1;i<len;i++){
    25                 global[i]=max(global[i-1],local[i]);
    26             }
    27         }
    28         int ans=global[len-1];        
    29         return ans;
    30     }
    31 };
    View Code

    local即为dp,表示局部最优解,global表示全局最优解

    注意要特判k>=n/2,leetcode没有给出数据范围,k很大时会tle或mle,k若大于n/2,相当于可以无限次买卖,贪心就可以。

  • 相关阅读:
    mssql like的效率
    【编辑器开发】基本js指令
    QQ菜单OUTLOOK风格
    oracle exp/imp命令详解
    javascript读取xml
    在c#中调用windows脚本的方法
    oracle常用命令(转)
    有效创建Oracle dblink的两种方式
    oracle 绑定变量(bind variable)
    Oracle备份与恢复
  • 原文地址:https://www.cnblogs.com/itcsl/p/8951739.html
Copyright © 2011-2022 走看看