让我们继续练习dp

首先这道题约束条件很多

但实际上方程还是很好写的,f[i,j]表示第i天时拥有j只股票的最大收益

令p=max(0,i-k-1) 上一次较交易

易得f[i,j]=max(f[i-1,j],f[p,j-b]-ap[i]*b,f[p,j+s]+bp[i]*s) b<=as[i],s<=bs[i];

显然会TLE,我们要优化

f[i-1,j]我们可以先不管他,

我们令j1=j-b  j2=j+s

则max(0,j-as[i])<=j1<=j

j<=j2<=min(m,j+bs[i]);

则原式可化为

f[i,j]=max(f[p,j1]+ap[i]*j1-ap[i]*j,f[p,j2]+bp[i]*j2-bp[i]*j)

观察得知对于当前的状态,结果只与j1,j2有关系

于是我们可以分开来对j1,j2求区间最大,再求一个总的最大就行

对此我们可以用线段树

但是,线段树算法O(n^2logn)而且实际常数较大,会TLE(一开始我就是这样)

观察区间其实总是整体右移的,这很像我一开始做的单调队列的滚动窗口那道题

于是我们可以用单调队列优化

加入只考虑买入的情况对于k1<k2

如果有f[p,k2]+ap[i]*k2>=f[p,k2]+ap[i]*k2 那么k2一定比k1优(更可能成为区间最大)

卖出情况同理,因此我们从0~m遍历一边,维护一个单调减的队列就行了

每个点最多出队一次,入队一次

因此复杂度为O(n^2);

 const inf=-;
var q,b,s,ns,nb,vs,vb:array[..] of longint;
    f:array[..,..] of longint;
    l,ans,h,t,p,i,j,k,n,m:longint; function max(a,b:longint):longint;
  begin
    if a>b then exit(a) else exit(b);
  end; function compareb(x,y:longint):boolean;
  begin
    if f[p,x]+vb[i]*x>=f[p,y]+vb[i]*y then exit(true) else exit(false);
  end; function compares(x,y:longint):boolean;
  begin
    if f[p,x]+vs[i]*x>=f[p,y]+vs[i]*y then exit(true) else exit(false);
  end; begin
  readln(n,m,k);
  for i:= to n do
    readln(vb[i],vs[i],nb[i],ns[i]);
  for i:= to m do
    f[,i]:=inf;
  f[,]:=;
  for i:= to n do
  begin
    p:=max(i-k-,);
    h:=;
    t:=;
    q[]:=;
    for j:= to m do   //买入情况
    begin
      if j<> then
      begin
        while (h<t) and compareb(j,q[t]) do dec(t);
        inc(t);
        q[t]:=j;
      end;
      l:=max(,j-nb[i]);
      while (q[h]<l) do inc(h);
      while (h<t) and compareb(q[h+],q[h]) do inc(h);
      b[j]:=f[p,q[h]]+vb[i]*q[h];
    end;
    h:=;
    t:=;
    q[]:=m;
    for j:=m downto do   //卖出情况
    begin
      if j<>m then
      begin
        while (h<t) and compares(j,q[t]) do dec(t);
        inc(t);
        q[t]:=j;
      end;
      l:=j+ns[i];
      if l>m then l:=m;
      while (q[h]>l) do inc(h);
      while (h<t) and compares(q[h+],q[h]) do inc(h);
      s[j]:=f[p,q[h]]+vs[i]*q[h];
    end;
    for j:= to m do   //求总的最大
      f[i,j]:=max(f[i-,j],max(b[j]-vb[i]*j,s[j]-vs[i]*j));
  end;
  ans:=f[n,];   //显然手上无股票最合算
  writeln(ans);
end.

bzoj1855的更多相关文章

  1. 【BZOJ1855】股票交易(动态规划,单调队列)

    [BZOJ1855]股票交易(动态规划,单调队列) 题面 BZOJ 题解 很显然,状态之和天数以及当天剩余的股票数有关 设\(f[i][j]\)表示第\(i\)天进行了交易,剩余股票数为\(j\)的最 ...

  2. 【bzoj1855】 [Scoi2010]股票交易 单调队列优化DP

    上一篇blog已经讲了单调队列与单调栈的用法,本篇将讲述如何借助单调队列优化dp. 我先丢一道题:bzoj1855 此题不难想出O(n^4)做法,我们用f[i][j]表示第i天手中持有j只股票时,所赚 ...

  3. 【BZOJ1855】[Scoi2010]股票交易 DP+单调队列

    [BZOJ1855][Scoi2010]股票交易 Description 最近lxhgww又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww预 ...

  4. BZOJ1855 [Scoi2010]股票交易 【单调队列优化dp】

    题目链接 BZOJ1855 题解 设\(f[i][j]\)表示第\(i\)天结束时拥有\(j\)张股票时的最大收益 若\(i \le W\),显然在这之前不可能有交易 \[f[i][j] = max\ ...

  5. [bzoj1855][Scoi2010]股票交易_动态规划_单调队列

    股票交易 bzoj-1855 Scoi-2010 题目大意:说不明白题意系列++...题目链接 注释:略. 想法:这个题还是挺难的. 动态规划没跑了 状态:dp[i][j]表示第i天手里有j个股票的最 ...

  6. bzoj1855: [Scoi2010]股票交易--单调队列优化DP

    单调队列优化DP的模板题 不难列出DP方程: 对于买入的情况 由于dp[i][j]=max{dp[i-w-1][k]+k*Ap[i]-j*Ap[i]} AP[i]*j是固定的,在队列中维护dp[i-w ...

  7. bzoj1855: [Scoi2010]股票交易

    Description 最近lxhgww又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww预测到了未来T天内某只股票的走势,第i天的股票买入价 ...

  8. BZOJ1855或洛谷2569 [SCOI2010]股票交易

    一道单调队列优化\(DP\) BZOJ原题链接 洛谷原题链接 朴素的\(DP\)方程并不难想. 定义\(f[i][j]\)表示到第\(i\)天,手上持有\(j\)股时的最大收益. 转移方程可以分成四个 ...

  9. BZOJ1855 股票交易 单调队列优化 DP

    描述 某位蒟佬要买股票, 他神奇地能够预测接下来 T 天的 每天的股票购买价格 ap, 股票出售价格 bp, 以及某日购买股票的上限 as,  某日出售股票上限 bs, 并且每次股票交 ♂ 易 ( 购 ...

随机推荐

  1. delphi 仅带下划线的TEdit控件

    在做录入框的时候,很希望有一个只带下划线的文本框,网上介绍的很多,有自己做组件的,须不知Delphi下只需要简单设置几个属性即可达到目的.

  2. Opencv Mat的操作

    cout << mat 有错误的原因 You are using OpenCV built with VS10. The ostream operator << in the ...

  3. WPF中让TextBlock每一个字符显示不同的颜色

    XAML代码: <TextBlock x:Name="tb"> <Run Foreground="Red">R</Run> ...

  4. 安装Ubuntu时,遇到自定义交换空间swap大小设置问题

    【整理】Ubuntu自定义分区设置 在安装Ubuntu时,如果使用的是一个新硬盘那么安装向导会建议你使用整个硬盘,如果硬盘上已经有数据了,向导会建议使用剩余的空间。不管怎样,是由向导自动划分的分区。 ...

  5. 基于SuperSocket实现的WebSocket(后端)

    关于WebSocket其实很早就想发了,奈何之前项目中的WebSocket的后端不是我做的,而我又想前后端都发出来和大家讨论讨论~于是挤出点时间研究了一下WebSocket的后端实现(所以才有了这篇文 ...

  6. iOS runtime 与 runloop

    runtime是运行时机制,就是运行到的时候才会执行的机制(类似于栏加载)属于时间先后性质的 runloop 是主线程的运行的意思   属于 (loop) 循环性质的 以下是 具体点的 解释: run ...

  7. 域名的a记录转过来他的公网ip

    首先 客户要我把域名 和项目进行绑定客户需要提供万网或者新网的账户,登进去域名管理  选项域名管理的A记录定向到那个公网ip上 与服务器做绑定然后 在服务器的iis 上 加个主机头 输入主机头名称 也 ...

  8. java多态与异常处理——动手动脑

    编写一个程序,此程序在运行时要求用户输入一个 整数,代表某门课的考试成绩,程序接着给出“不及格”.“及格”.“中”.“良”.“优”的结论. 要求程序必须具备足够的健壮性,不管用户输入什 么样的内容,都 ...

  9. 1044: [HAOI2008]木棍分割 - BZOJ

    Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, 砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长 ...

  10. window.location.hash属性介绍

    location是javascript里边管理地址栏的内置对象,比如location.href就管理页面的url,用location.href=url就可以直接将页面重定向url.而location. ...