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;
    }
    苟利国家生死以, 岂因祸福避趋之。
  • 相关阅读:
    以太网数据帧最小64字节
    网络基础协议之ARP
    Windows FAT32转换NTFS
    Java面试红宝书(尼恩编著)
    死磕设计模式1:Builder (构建者模式)
    Zookeeper 分布式锁 (图解+秒懂+史上最全)
    TCP/IP协议 (图解+秒懂+史上最全)
    Java高并发核心编程(卷2):多线程、锁、JMM、JUC、高并发设计模式
    Java高并发核心编程(卷1):NIO、Netty、Redis、ZooKeeper
    ThreadLocal(史上最全)
  • 原文地址:https://www.cnblogs.com/TSHugh/p/6986322.html
Copyright © 2011-2022 走看看