zoukankan      html  css  js  c++  java
  • 【BZOJ】【1855】【SCOI2010】/【HDOJ】【3401】股票交易

    DP/单调队列优化


      题解:http://www.cnblogs.com/jianglangcaijin/p/3799736.html

      令f[i][j]表示第 i 天结束后,手里剩下 j 股的最大利润,则有:

        [  f[i][j]= egin{cases} f[i-1][j] &   &{(不买不卖)}\ f[i-w-1][k]-ap[i]*(j-k)&   &{ j-as[i] leq k leq j-1 (买入)}\ f[i-w-1][k]+bp[i]*(k-j)&   &{ j+1 leq k leq j+bs[i] (卖出)} end{cases} ]

      对于买入,我们将式子变形得到:

        $$ f[i][j]=f[i-w-1][k]+ap[i]*k-ap[i]*j $$

      我们知道单调队列优化可以将形如 $ f[i]=max/min { f[k] }+g[i] $ 的式子中对k的枚举利用队列进行优化,这个式子中,"f[k]" 即是 $ f[i-w-1][k]+ap[i]*k $,“g[i]”即是 $ -ap[i]*j $,所以我们在枚举 j 的同时即可完成对k的维护(即每个f[i]都是一次单调队列优化下的DP)

      而卖出同理。

     1 /**************************************************************
     2     Problem: 1855
     3     User: Tunix
     4     Language: C++
     5     Result: Accepted
     6     Time:380 ms
     7     Memory:17068 kb
     8 ****************************************************************/
     9  
    10 //BZOJ 1855
    11 #include<cmath>
    12 #include<vector>
    13 #include<cstdio>
    14 #include<cstring>
    15 #include<cstdlib>
    16 #include<iostream>
    17 #include<algorithm>
    18 #define rep(i,n) for(int i=0;i<n;++i)
    19 #define F(i,j,n) for(int i=j;i<=n;++i)
    20 #define D(i,j,n) for(int i=j;i>=n;--i)
    21 #define pb push_back
    22 using namespace std;
    23 int getint(){
    24     int v=0,sign=1; char ch=getchar();
    25     while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
    26     while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
    27     return v*=sign;
    28 }
    29 const int N=2010,INF=~0u>>2;
    30 typedef long long LL;
    31 /******************tamplate*********************/
    32  
    33 struct node{
    34     int x,y;
    35     node(int _=0,int __=0):x(_),y(__){}
    36 }q[N];
    37 int f[N][N];
    38 int main(){
    39 #ifndef ONLINE_JUDGE
    40     freopen("1855.in","r",stdin);
    41     freopen("1855.out","w",stdout);
    42 #endif
    43     int n=getint(),m=getint(),w=getint();
    44     F(i,0,n) F(j,0,m) f[i][j]=-INF;
    45     int ans=0,ap,bp,as,bs;
    46     F(i,1,n){
    47         ap=getint(); bp=getint(); as=getint(); bs=getint();
    48         F(j,0,as) f[i][j]=-ap*j;
    49         F(j,0,m) f[i][j]=max(f[i][j],f[i-1][j]);
    50         int k=i-w-1;
    51         if (k>=0){
    52             int st=0,ed=0;
    53             F(j,0,m){
    54                 while(st<ed && q[st].x<j-as) st++;
    55                 while(st<ed && q[ed-1].y<=f[k][j]+ap*j) ed--;
    56                 q[ed++]=node(j,f[k][j]+ap*j);
    57                 if (st<ed) f[i][j]=max(f[i][j],q[st].y-ap*j);
    58             }
    59             st=ed=0;
    60             D(j,m,0){
    61                 while(st<ed && q[st].x>j+bs) st++;
    62                 while(st<ed && q[ed-1].y<=f[k][j]+bp*j) ed--;
    63                 q[ed++]=node(j,f[k][j]+bp*j);
    64                 if (st<ed) f[i][j]=max(f[i][j],q[st].y-bp*j);
    65             }
    66         }
    67         ans=max(ans,f[i][0]);
    68     }
    69     printf("%d
    ",ans);
    70     return 0;
    71 }
    View Code
  • 相关阅读:
    mysql 历史版本下载
    mysql 5.7 版本 You must reset your password using ALTER USER statement before executing this statement报错处理
    5.7 zip 版本的安装 以及遇到的坑
    mysql 5.6zip版本的卸载与5.7 zip 版本的安装
    mysql数据库的备份与还原
    本地Navicat连接docker里的mysql
    docker修改数据库密码
    docker 在push镜像到本地registry出现的500 Internal Server Error
    linux 没有界面内容显示不全解决办法
    json与map互相转换
  • 原文地址:https://www.cnblogs.com/Tunix/p/4321486.html
Copyright © 2011-2022 走看看