股票交易——单调队列优化DP
题目描述

思路
蒟蒻还是太弱了,,就想到半个方程就GG了,至于什么单调队列就更想不到了。
$f[i][j]$表示第$i天有j$张股票的最大收益。
那么有四种选择:
- 不买股票:$f[i][j]=max(f[i][j],f[i-1][j])$
- 买$j$张股票,之前没有买:$f[i][j]=-j*ap[i]$
- 买$j$张股票,之前有过交易,中间间隔了$w$天:$f[i][j]=max(f[i][j],f[i-w-1][k]-(j-k)*ap[i])$
- 卖$j$张股票,之前有过交易(废话),中间间隔了$w$天,$f[i][j]=max(f[i][j],f[i-w-1][k]+(k-j)*bp[i])$
方程列出来了,还是很好理解的。那么怎么优化呢?我们发现$i,j,k$都要枚举$O(n^3)$的复杂度是会$T$的,我们需要用一些优化。
我们发现:3转移中$f[i-w-1][k]-(j-k)*ap[i]=f[i-w-1][k]+k*ap[i]-j*ap[i]$,这样我们在第i天时只要找出最大的$f[i-w-1][k]+k*ap[i]$即可,因为前两维$i,j$已知,$j*ap[i]$是常数。
用一个递减的单调队列维护使$f[i-w-1][k]+k*ap[i]$最大的$k$,每次取队首转移即可,注意如果$as[i]<j-k$(即买不了这么多股票)时,需要把队首弹出。那么4也是一样,维护最大的$f[i-w-1][k]+k*bp[i](bs[i]<k-j)$
code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int N=;
int n,m,w,ap,bp,as,bs;
int f[N][N],q[N],head,tail; int main()
{
scanf("%d%d%d",&n,&m,&w);
memset(f,,sizeof(f));//负无穷
for(int i=;i<=n;i++)
{
scanf("%d%d%d%d",&ap,&bp,&as,&bs);
for(int j=;j<=as;j++)f[i][j]=-ap*j;//转移2
for(int j=;j<=m;j++)f[i][j]=max(f[i-][j],f[i][j]);//转移1
if(i<=w)continue;//之前不能进行交易
head=,tail=;
for(int j=;j<=m;j++)
{
while(head<=tail&&q[head]<j-as)
head++;//不够买
while(head<=tail&&f[i-w-][q[tail]]+q[tail]*ap<=f[i-w-][j]+j*ap)
tail--;//单调性
q[++tail]=j;//加入新元素
if(head<=tail)
f[i][j]=max(f[i][j],f[i-w-][q[head]]+q[head]*ap-j*ap);//转移3
}
head=,tail=;
for(int j=m;j>=;j--)
{
while(head<=tail&&q[head]>j+bs)
head++;//不够卖
while(head<=tail&&f[i-w-][q[tail]]+q[tail]*bp<=f[i-w-][j]+j*bp)
tail--;//单调性
q[++tail]=j;//加入新元素
if(head<=tail)
f[i][j]=max(f[i][j],f[i-w-][q[head]]+q[head]*bp-j*bp);//转移4
}
}
cout<<f[n][];//最后一天全部卖出即为最优
}
股票交易——单调队列优化DP的更多相关文章
- 1855: [Scoi2010]股票交易[单调队列优化DP]
1855: [Scoi2010]股票交易 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1083 Solved: 519[Submit][Status] ...
- 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 ...
- 【bzoj1855】 [Scoi2010]股票交易 单调队列优化DP
上一篇blog已经讲了单调队列与单调栈的用法,本篇将讲述如何借助单调队列优化dp. 我先丢一道题:bzoj1855 此题不难想出O(n^4)做法,我们用f[i][j]表示第i天手中持有j只股票时,所赚 ...
- SCOI 股票交易 单调队列优化dp
这道题 我很蒙.....首先依照搞单调队列优化dp的一般思路 先写出状态转移方程 在想法子去优化 这个题目中说道w就是这一天要是进行操作就是从前w-1天转移而来因为之前的w天不允许有操作!就是与这些天 ...
- 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 ...
- LUOGU P2569 [SCOI2010]股票交易(单调队列优化dp)
传送门 解题思路 不难想一个\(O(n^3)\)的\(dp\),设\(f_{i,j}\)表示第\(i\)天,手上有\(j\)股的最大收益,因为这个\(dp\)具有单调性,所以\(f_i\)可以贪心的直 ...
- BZOJ 1855 股票交易 - 单调队列优化dp
传送门 题目分析: \(f[i][j]\)表示第i天,手中拥有j份股票的最优利润. 如果不买也不卖,那么\[f[i][j] = f[i-1][j]\] 如果买入,那么\[f[i][j] = max\{ ...
- BZOJ1855 股票交易 单调队列优化 DP
描述 某位蒟佬要买股票, 他神奇地能够预测接下来 T 天的 每天的股票购买价格 ap, 股票出售价格 bp, 以及某日购买股票的上限 as, 某日出售股票上限 bs, 并且每次股票交 ♂ 易 ( 购 ...
- 2018.09.10 bzoj1855: [Scoi2010]股票交易(单调队列优化dp)
传送门 单调队列优化dp好题. 有一个很明显的状态设置是f[i][j]表示前i天完剩下了j分股票的最优值. 显然f[i][j]可以从f[i-w-1][k]转移过来. 方程很好推啊. 对于j<kj ...
随机推荐
- Solidity 编程实例--简单的公开拍卖
通常简单的公开拍卖合约,是每个人可以在拍卖期间发送他们的竞拍出价.为了实现绑定竞拍人的到他们的拍卖,竞拍包括发送金额/ether.如果产生了新的最高竞拍价,前一个最高价竞拍人将会拿回他的钱.在竞拍阶段 ...
- docker镜像命令使用
创建docker容器时使用的docker镜像如果在本地中不存在,docker就会自动从docker镜像仓库中下载,默认的docker镜像仓库是Docker Hub公共镜像源 使用docker sear ...
- 对象模型(Object-Model):关于vptr、vtbl
当一个类本身定义了虚函数,或其父类有虚函数时,为了支持多态机制,编译器将为该类添加一个虚函数指针(vptr).虚函数指针一般都放在对象内存布局的第一个位置上,这是为了保证在多层继承或多重继承的情况下能 ...
- java零碎知识(每种数据类型默认值,多大,取值范围)
只要记下字节就好了 其它不必死记,取值范围:没有正负的,2的 字节数*8次方-1 , 凡是有正负的2的 (字节数*8)-1次方 -1 比如: 1.byte(有正负):先计算是2的几次方:字节数1*( ...
- 自学web前端达到什么水平,才能满足求职的标准?
大多数野生程序员最棘手的问题就是如何依靠技术解决温饱,通俗来讲就是技术折现的问题. 如果是单纯出于兴趣,或者只是为了突击某一阶段或者某一项目技术壁垒,不跟就业挂钩的自学倒也是无关痛痒.但是当上岗成为自 ...
- PowerUp攻击模块实战
PowerUp攻击模块实战 1.将PowerUp.ps1脚本上传至目标服务器,然后在本地执行 2.使用IEX在内存中加载此脚本,执行以下命令,脚本将进行所有的检查. powershell.exe ...
- 同一台机上配置多个redis服务
"D:\Program Files\Redis\redis-server.exe" --service-run F:Redis2\redis.windows-service6380 ...
- Service Mesh 初体验
前言 计算机软件技术发展到现在,软件架构的演进无不朝着让开发者能够更加轻松快捷地构建大型复杂应用的方向发展.容器技术最初是为了解决运行环境的不一致问题而产生的,随着不断地发展,围绕容器技术衍生出来越来 ...
- 利用电脑开启自带虚拟wifi,无需第三方工具。
注:此方法只验证win 7以上系统,XP server 2016 系统未验证 1.新建记事本,在记事本中输入netsh wlan set hostednetwork mode=allow ssid= ...
- Python的Argparse模块是什么?
近日在阅读代码的过程中遇到了Argparse模块,记得前段时间已经看了,可是过了两周现在又忘了, 看来写代码一定要钻研到底搞清楚其中原委才行,本文主要参考Python3.6系列官方文档 ...