• 【BZOJ1855】[Scoi2010] 股票交易


    →BZOJ任意门←

    很显然的动态规划题(笑)

    容易想到DP的数组 f[i][j] 表示第i天手上有j股股票时能赚到最多的钱。

    接下来就是转移了,有这么多变量一定要看清楚,仔细地分情况讨论。

    每次转移时一共有四种情况:

    (先从简单的入手)

    一、第i天不买股票也不买

    那就是从前一天相同的股票值更新过来

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

    那为什么是前一天而不是前几天呢?因为前几天的最优值都已经更新到前一天了呀。

    二、第i天凭空买股票(相当于从之前手持0股票的情况更新来)

    其实就是第i天的DP数组的初始化

    For(j,0,As[i]) f[i] [j]=-1 * j * Ap[i];

    三、第i天在第 i-w-1 天的基础上买股票

    那我们设第i-w-1天的股票数为k,最直接的更新就是下面这样

    f[i][j]=max(f[i][j], f[i-w-1][k]-(j-k)* Ap[i]);

    但我们此时要更新的是j,所以可以稍稍转化一下:

      f[i][j]=max{ f[i-w-1][k]+k*Ap[i] } - j* Ap[i]

    那么此时k的范围是多少呢 不难想到就是 [ j-As[i], j)

    所以在k的取值范围上,有经验的OIer们应该都能想到单调队列了吧(!)

    式子中有取max值,还有取值范围的经常都是用单调队列来优化(不知道具体如何操作的可以看代码)

    四、第i天在第i-w-1天的基础上卖出股票

    和上一种情况其实是一样的(式子的推导请参照上式自己操作)

    f[i][j]=max{f[i-w-1][k]+k*Bp[i]}- j* Ap[i]

    只是k的取值范围不一样了,变成了(j, j+Bs[i] ]

    同样可以用单调队列来优化。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<algorithm>
     6 
     7 #define For(i,a,b) for(register int i=a;i<=b;++i)
     8 #define Dwn(i,a,b) for(register int i=a;i>=b;--i)
     9 #define Re register 
    10 
    11 using namespace std;
    12 
    13 const int N=2e3+10;
    14 int f[N][N],q[N*2],qf,qr;
    15 int n,m,As[N],Ap[N],Bs[N],Bp[N],W,T,MaxP;
    16 inline void read(int &v){
    17     v=0;
    18     char c=getchar();
    19     while(c<'0'||c>'9')c=getchar();
    20     while(c>='0'&&c<='9')v=v*10+c-'0',c=getchar();
    21 }
    22 int main(){
    23     read(T); read(MaxP); read(W);
    24     For(i,1,T){
    25         read(Ap[i]); read(Bp[i]);
    26         read(As[i]); read(Bs[i]);
    27     }
    28     memset(f,128,sizeof(f));
    29     For(i,1,T){
    30         // I bought some stocks from nowhere
    31         For(j,0,As[i]){
    32             f[i][j]=-1*j*Ap[i];
    33         }
    34         // I didn't buy anything
    35         For(j,0,MaxP){
    36             f[i][j]=max(f[i][j],f[i-1][j]);
    37         }
    38         
    39         if(i-W-1<=0)continue;
    40         
    41         // I bought some stock today after W days
    42         qf=1; qr=0;
    43         For(j,0,MaxP){
    44             while(qf<=qr&&q[qf]<j-As[i])qf++; 
    45             if(qf<=qr){
    46                 int k=q[qf];
    47                 f[i][j]=max(f[i][j],f[i-W-1][k]+k*Ap[i]-j*Ap[i]);
    48             }  
    49             while(qf<=qr&&f[i-W-1][q[qr]]+q[qr]*Ap[i]<=f[i-W-1][j]+j*Ap[i])qr--;
    50             q[++qr]=j;
    51         }
    52      
    53         // I sold some stock today after W days
    54         qf=1; qr=0;
    55         Dwn(j,MaxP,0){
    56             while(qf<=qr&&q[qf]>j+Bs[i])qf++;
    57             if(qf<=qr){
    58                 int k=q[qf];
    59                 f[i][j]=max(f[i][j],f[i-W-1][k]+k*Bp[i]-j*Bp[i]);
    60             }
    61             while(qf<=qr&&f[i-W-1][q[qr]]+q[qr]*Bp[i]<=f[i-W-1][j]+j*Bp[i])qr--;
    62             q[++qr]=j;
    63         }
    64     }
    65     int fn=-2147483600;
    66     For(i,0,MaxP)fn=max(fn,f[T][i]);
    67     cout<<fn<<endl;
    68     return 0;
    69 }
  • 相关阅读:
    spring-cloud 注册中心配置
    SpringMVC执行流程和原理
    ssm 框架整合 配置
    Spring整合ActiveMQ 之 ActiveMQ配置
    redis配置代码
    world
    web服务器和web应用服务器的区别?
    经典面试题:Mybatis原理
    springmvc原理|执行过程|解决了什么问题?
    Hadoop 学习目录(搁置)
  • 原文地址:https://www.cnblogs.com/HLAUV/p/9925646.html
Copyright © 2020-2023  润新知