zoukankan      html  css  js  c++  java
  • SCOI 股票交易 单调队列优化dp

    这道题 我很蒙.....
    首先依照搞单调队列优化dp的一般思路 先写出状态转移方程 在想法子去优化

    这个题目中说道w就是这一天要是进行操作就是从前w-1天转移而来因为之前的w天
    不允许有操作!就是与这些天的状态无关!
    那么每一天更新那一天已经定了那么他对后面要转移的地方的影响就是手里的票了
    既然这样就加一维表示
    f[i][j]表示到第i天手里有j个票的最大收益这样就无后效性了
    f[i][j]=Max(f[i][j],f[last][x]-(j-x)*in[i]);
    f[i][j]=Max(f[i][j],f[last][x]+(x-j)*out[i]);
    f[i][j]=Max(f[i][j],f[i-1][j]);
    三种最大即为所求(第三种是不进行任何操作根据状态数组的增性就用前一个状态来修改就行了)
    我很蒙......

    #include<cstdio>
    #include<queue>
    #include<cstring>
    using namespace std;
    int f[2005][2005],in[2005],out[2005],inm[2005],outm[2005];
    int t,mp,w;
    deque<int>q;
    inline int Max(int x,int y)
    {
        return x>y?x:y;
    }
    inline void push(int i,int j,int x)
    {
        while(!q.empty())
        {
          int y=q.back();
          if(f[i][j]>=f[i][y]-in[x]*(j-y))q.pop_back();
          else{ q.push_back(j);break;}
        }
        if(q.empty())q.push_back(j);
    }
    inline void pop1(int j)
    {
         while(q.front()>j&&!q.empty())q.pop_front();
    }
    inline void push1(int i,int j,int x)
    {
        while(!q.empty())
        {
          int y=q.back();
          if(f[i][j]>=f[i][y]+out[x]*(y-j))q.pop_back();
          else{ q.push_back(j);break;}
        }
        if(q.empty())q.push_back(j);
    }
    inline void pop(int j)
    {
         while(q.front()<j&&!q.empty())q.pop_front();
    }
    int main()
    {
         
        scanf("%d%d%d",&t,&mp,&w);
        memset(f,0xaf,sizeof(f));
        for(int i=1;i<=t;i++)scanf("%d%d%d%d",&in[i],&out[i],&inm[i],&outm[i]);
        for(int i=1;i<=w+1&&i<=t;i++)
        {
         f[i][0]=0;
         for(int j=1;j<=inm[i];j++)
          f[i][j]=f[i][j-1]-in[i];
         for(int j=0;j<=mp;j++)
          f[i][j]=Max(f[i][j],f[i-1][j]);
        }
        for(int i=w+2,last=1;i<=t;i++,last++)
        {
          q.clear();
          for(int j=0;j<=mp;j++)
          {
            pop(j-inm[i]);
            push(last,j,i);
            int x=q.front();
            f[i][j]=Max(f[i][j],f[last][x]-(j-x)*in[i]);
          }
          q.clear();
          for(int j=mp;j>=0;j--)
          {
            pop1(j+outm[i]);
            push1(last,j,i);
            int x=q.front();
            f[i][j]=Max(f[i][j],f[last][x]+(x-j)*out[i]);
          }
          for(int j=0;j<=mp;j++)
            f[i][j]=Max(f[i][j],f[i-1][j]);
        }
        int ans=0;
        for(int i=0;i<=mp;i++)ans=Max(ans,f[t][i]);
        printf("%d",ans);
        return 0;
    }
    苟利国家生死以, 岂因祸福避趋之。
  • 相关阅读:
    Linux mii-tool 命令
    MySQL 主从复制
    MySQL 备份与恢复
    SOAP 版本可能不匹配: 出现意外的 Envelope 命名空间 http://schemas.xmlsoap.org/wsdl/
    网管邮件配置
    ORA-10873
    Exception in thread "main" java.lang.UnsatisfiedLinkError:
    安装 ORACLE 11G出现Error Message:PRVF-7535
    mount /dev/sr0 /media/cdrom you must specify the filesystem type
    NBU 还原windows ORACLE数据库(BW)
  • 原文地址:https://www.cnblogs.com/TSHugh/p/6986322.html
Copyright © 2011-2022 走看看