股票交易



$ solution: $

这道题以前就写了,题目很好,但自己没有发题解,来补一篇:

首先,题目出得很有迷惑性,但我们不难想到状态要设天数,和自己手上的股票数目(因为这两个就是充要信息)。而我们转移也比较常规,跟着题意模拟就行:

  1. (不买不卖): $ f[i][j]=f[i-1][j] $
  2. (买入): $ f[i][j]=max{~\sum_{p=1}^{p<i} \sum_{q=0}^{q<j} f[p][q]-(j-q)\times AP[i]~} $
  3. (卖出): $ f[i][j]=max{~\sum_{p=1}^{p<i} \sum_{q=0}^{q>j} f[p][q]+(q-j)\times BP[i]~} $

但是我们发现这样转移是 $ n^4 $ 的。因为我们每一个 $ f[i][j] $ 需要往前枚举 $ p $ ,然后因为股票可以买入卖出,还要枚举一个 $ q $ 。就是每一个 $ f[i][j] $ 都要完全枚举所有的 $ f[p][q] $ 来转移。但是我们可以发现我们的 $ p $ 是完全可以不用枚举,因为第一个转移保证了 $ f[i-1] $ 就是最优的。于是转移变成了 $ n^3 $ 但是数据范围告诉我们这样还不够。

  1. (买入): $ f[i][j]=max{~\sum_{k=1}^{k<j} f[i-1][k]-(j-k)\times AP[i]~} $
  2. (卖出): $ f[i][j]=max{~\sum_{k=1}^{k>j} f[i-1][k]+(k-j)\times BP[i]~} $

这两个式子其实把括号拆开后就是一个式子:

$ f[i][j]=max{~\sum_{k=1}^{k>j} f[i-1][k]+k\times P[i]-j\times P[i]~} $

单调队列优化: 我们发现我们买入卖出的式子是一个变量单调递增的,我们的 $ i $ 是最外层循环,在内层循环里它相当于定值,而我们的k和j在式子中是独立的,完全可以用单调队列维护 $ f[i-1][k]+k\times P[i] $ ,而 $ -j\times P[i] $ 就是定值,只需要来两次单调队列分别对应 $ AP[i] $ 和 $ BP[i] $ 即可。



$ code: $

#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set> #define ll long long
#define db double
#define inf 0x7fffffff
#define rg register int
#define max(A,B) (A>B?A:B) using namespace std; int n,m,w,l,r,now,a,b,c,d,ans;
int f[2001][2001],t[2001],p[2001]; inline int qr(){
char ch;
while((ch=getchar())<'0'||ch>'9');
int res=ch^48;
while((ch=getchar())>='0'&&ch<='9')
res=res*10+(ch^48);
return res;
} int main(){
//freopen("1.in","r",stdin);
//freopen(".out","w",stdout);
n=qr(),m=qr(),w=qr();
for(rg i=0;i<=n;++i)
for(rg j=0;j<=m;++j)
f[i][j]=-inf;
for(rg i=1;i<=n;++i){
a=qr(),b=qr();
c=qr(),d=qr();
for(rg j=0;j<=c;++j)
f[i][j]=-1*j*a;
for(rg j=0;j<=m;++j)
f[i][j]=max(f[i][j],f[i-1][j]);
if(i<=w)continue;
l=1;r=0;
for(rg j=0;j<=m;++j){
now=f[i-w-1][j]+j*a;
while(l<=r&&p[l]<j-c)++l;
while(l<=r&&t[r]<=now)--r;
t[++r]=now;p[r]=j;
if(l <= r)f[i][j]=max(f[i][j],t[l]-j*a);
}
l=1;r=0;
for(rg j=m;j>=0;--j){
now=f[i-w-1][j]+j*b;
while(l<=r&&p[l]>j+d)++l;
while(l<=r&&t[r]<=now)--r;
t[++r]=now;p[r]=j;
if(l <= r)f[i][j]=max(f[i][j],t[l]-j*b);
}
}
for(rg j=0;j<=m;++j)
ans=max(ans,f[n][j]);
printf("%d\n",ans);
return 0;
}

股票交易 (单调队列优化DP)的更多相关文章

  1. 1855: [Scoi2010]股票交易[单调队列优化DP]

    1855: [Scoi2010]股票交易 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1083  Solved: 519[Submit][Status] ...

  2. 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 ...

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

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

  4. SCOI 股票交易 单调队列优化dp

    这道题 我很蒙.....首先依照搞单调队列优化dp的一般思路 先写出状态转移方程 在想法子去优化 这个题目中说道w就是这一天要是进行操作就是从前w-1天转移而来因为之前的w天不允许有操作!就是与这些天 ...

  5. bzoj1855: [Scoi2010]股票交易 单调队列优化dp ||HDU 3401

    这道题就是典型的单调队列优化dp了 很明显状态转移的方式有三种 1.前一天不买不卖: dp[i][j]=max(dp[i-1][j],dp[i][j]) 2.前i-W-1天买进一些股: dp[i][j ...

  6. LUOGU P2569 [SCOI2010]股票交易(单调队列优化dp)

    传送门 解题思路 不难想一个\(O(n^3)\)的\(dp\),设\(f_{i,j}\)表示第\(i\)天,手上有\(j\)股的最大收益,因为这个\(dp\)具有单调性,所以\(f_i\)可以贪心的直 ...

  7. BZOJ 1855 股票交易 - 单调队列优化dp

    传送门 题目分析: \(f[i][j]\)表示第i天,手中拥有j份股票的最优利润. 如果不买也不卖,那么\[f[i][j] = f[i-1][j]\] 如果买入,那么\[f[i][j] = max\{ ...

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

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

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

    题目描述 思路 蒟蒻还是太弱了,,就想到半个方程就GG了,至于什么单调队列就更想不到了. $f[i][j]$表示第$i天有j$张股票的最大收益. 那么有四种选择: 不买股票:$f[i][j]=max( ...

  10. 2018.09.10 bzoj1855: [Scoi2010]股票交易(单调队列优化dp)

    传送门 单调队列优化dp好题. 有一个很明显的状态设置是f[i][j]表示前i天完剩下了j分股票的最优值. 显然f[i][j]可以从f[i-w-1][k]转移过来. 方程很好推啊. 对于j<kj ...

随机推荐

  1. MVP 实战

    那么我们下面就要将这个类中的代码改写为 MVP 的写法,回顾上面提及的 MVP 架构的思想,它是将 View 层与 Model 层彻底隔离,意味着 View 和 Model 都不再持对方的引用,它们通 ...

  2. CentOS6.5/7安装配置Samba

    CentOS6.5安装配置Samba 本文的场景是虚拟机运行CentOS6.,本机是Win7,现欲把CentOS上的一个文件夹共享出来,Win的机器可以读写. Samba与window连接需要使用Ne ...

  3. layer系列之弹层layer.prompt

    layer官网:https://www.layui.com/doc/modules/layer.html layer在线调试:http://layer.layui.com/ 如何使用layer.pro ...

  4. spark 学习网站和资料

    spark 官网首页 https://spark.apache.org/ spark 官网文档 spark scala API 文档 https://spark.apache.org/docs/lat ...

  5. qbzt day4 下午

    有向图的强连通分量 强联通:两个点之间可以互相到达 如果某个图任意两个点都是强联通的,那么称这个图强联通 如果一个图的子图是强联通的,那么称这个图是强联通子图 一个图的极大强联通子图被称作强连通分量 ...

  6. nginx 入门 安装

    .yum解决编译nginx所需的依赖包,之后你的nginx就不会报错了 yum install gcc patch libffi-devel python-devel zlib-devel bzip2 ...

  7. ConcurrentSkipListMap 源码分析

    ConcurrentSkipListMap ConcurrentSkipListMap 能解决什么问题?什么时候使用 ConcurrentSkipListMap? 1)ConcurrentSkipLi ...

  8. 像计算机科学家一样思考python-第3章 函数

    在程序设计中,函数是指用于进行某种计算的一系列语句的有名称的组合.定义一个函数时,需要指定函数的名称并写下一系列程序语句.之后,就可以使用名称来“调用”这个函数 3.1函数调用 一个函数调用的例子 & ...

  9. 关于崩溃报告的日志以及dump文件

    在用户使用软件的过程当中突然产生软件崩溃的问题,必须采取相关的措施去拦截崩溃产生的原因,这有助于程序员解决此类崩溃的再次发生.特别是有些难以复现的崩溃,不稳定的崩溃,更有必要去调查崩溃产生的原因.一般 ...

  10. object数据类型

    1 object数据类型是dataframe中特殊的数据类型,当某一列出现数字.字符串.特殊字符和时间格式两种及以上时,就会出现object类型,即便把不同类型的拆分开,仍然是object类型. 如下 ...