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]=max(dp[i-W-1][k]-(j-k)*AP[i],dp[i][j])
3、前i-W-1天卖掉一些股: dp[i][j]=max(dp[i-W-1][k]+(k-j)*BP[i],dp[i][j])
第一种转移是o(1)的 第二种如果枚举k时间复杂度接受不了八成是要T的 观察一下后发现 因为一般可以用单调队列优化的DP都能满足形如f[x]=max(min){f[k]}+g[x]
所以我们可以转换一下方程 dp[i][j]=max(dp[i-W-1][k]+k*AP[i])-j*AP[i]。令f[i-W-1][k]=dp[i-W-1][k]+k*AP[i],则dp[i][j]=max(f[i-W-1][k]) - j*AP[i]。
这样之后就可以用单调队列优化了呀。
注意买的j要从0~mxa而卖的应该是mxa~0 虽然都是这是因为买的时候是k+as【i】 而卖的时候是k-bs【i】的原因 其余的看代码咯
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=,inf=0x3f3f3f3f;
int read(){
int ans=,f=,c=getchar();
while(c<''||c>''){if(c=='-') f=-; c=getchar();}
while(c>=''&&c<=''){ans=ans*+(c-''); c=getchar();}
return ans*f;
}
struct node{int pos,f;}e[M];
int n,mxa,w,ans,head,tail;
int ap[M],bp[M],as[M],bs[M],dp[M][M];
int main()
{
n=read(); mxa=read(); w=read();
for(int i=;i<=n;i++) ap[i]=read(),bp[i]=read(),as[i]=read(),bs[i]=read();
for(int i=;i<=n;i++) for(int j=;j<=mxa;j++) dp[i][j]=-inf;
for(int i=;i<=w+;i++) for(int j=;j<=min(mxa,as[i]);j++) dp[i][j]=-ap[i]*j;
dp[][]=;
for(int i=;i<=n;i++){
for(int j=;j<=mxa;j++) dp[i][j]=max(dp[i-][j],dp[i][j]);
if(i<=w+) continue;
int now=i-w-;
head=; tail=;
for(int j=;j<=mxa;j++){
int nowf=dp[now][j]+j*ap[i];
while(head<tail&&nowf>e[tail-].f) tail--;
e[tail].f=nowf; e[tail++].pos=j;
while(head<tail&&e[head].pos+as[i]<j) head++;
dp[i][j]=max(dp[i][j],e[head].f-j*ap[i]);
}
head=; tail=;
for(int j=mxa;j>=;j--){
int nowf=dp[now][j]+j*bp[i];
while(head<tail&&nowf>e[tail-].f) tail--;
e[tail].f=nowf; e[tail++].pos=j;
while(head<tail&&e[head].pos-bs[i]>j) head++;
dp[i][j]=max(dp[i][j],e[head].f-j*bp[i]);
}
}
printf("%d\n",dp[n][]);
return ;
}
最后强调一下 别的题解最后的答案有的是从dp【n】【0~mxa】或者是dp【0~n】【0】里面寻找答案但是我觉得如果最佳答案早dp【n】【0~mxa】里那肯定是手里没有持有股票都卖掉了才赚好吧所以答案肯定是dp【n】【0】 如果答案在dp【0~n】【0】那任意的最优解肯定能通过不买不卖的方式转移到dp【n】【0】所以答案就是dp【n】【0】了啦
bzoj1855: [Scoi2010]股票交易 单调队列优化dp ||HDU 3401的更多相关文章
- 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只股票时,所赚 ...
- 1855: [Scoi2010]股票交易[单调队列优化DP]
1855: [Scoi2010]股票交易 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1083 Solved: 519[Submit][Status] ...
- LUOGU P2569 [SCOI2010]股票交易(单调队列优化dp)
传送门 解题思路 不难想一个\(O(n^3)\)的\(dp\),设\(f_{i,j}\)表示第\(i\)天,手上有\(j\)股的最大收益,因为这个\(dp\)具有单调性,所以\(f_i\)可以贪心的直 ...
- SCOI 股票交易 单调队列优化dp
这道题 我很蒙.....首先依照搞单调队列优化dp的一般思路 先写出状态转移方程 在想法子去优化 这个题目中说道w就是这一天要是进行操作就是从前w-1天转移而来因为之前的w天不允许有操作!就是与这些天 ...
- 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, 并且每次股票交 ♂ 易 ( 购 ...
- BZOJ1855 [Scoi2010]股票交易[单调队列dp]
题 题面有点复杂,不概括了. 后面的状态有前面的最优解获得大致方向是dp.先是瞎想了个$f[i][j]$表示第$i$天手里有$j$张股票时最大收入(当天无所谓买不买). 然后写了一个$O(n^4)$状 ...
- 股票交易——单调队列优化DP
题目描述 思路 蒟蒻还是太弱了,,就想到半个方程就GG了,至于什么单调队列就更想不到了. $f[i][j]$表示第$i天有j$张股票的最大收益. 那么有四种选择: 不买股票:$f[i][j]=max( ...
随机推荐
- guacamole实现上传下载
目录 1. 源码解读 2. 上传下载的核心代码 分析的入手点,查看websocket连接的frame 看到首先服务端向客户端发送了filesystem请求,紧接着浏览器向服务端发送了get请求,并且后 ...
- Linux的系统安全设置Shell脚本
#!/bin/sh # desc: setup linux system security # powered by www.lvtao.net #account setup passwd -l xf ...
- runtime总结 iOS
Runtime的特性主要是消息(方法)传递,如果消息(方法)在对象中找不到,就进行转发,具体怎么实现的呢.我们从下面几个方面探寻Runtime的实现机制. Runtime介绍 Runtime消息传递 ...
- JavaScript函数constructor的作用,意义
前几天写了一片 如何用正确的姿势编写jQuery插件 有朋友拍砖,指正.再此谢谢! 讨论:指定函数的constructor作用到底是什么? 我们一般写jQuery插件的时候是这样的: //构造函数 f ...
- Python 3基础教程23-多维列表
这里简单举例一个多维列表,多维看起来都很晕. # 多维列表 x = [ [5,6],[6,7],[7,2] ,[2,5] ,[4,9]] print(x) # 根据索引引用列表元素,例如打印[6,7] ...
- bam文件测序深度统计-bamdst
最近接触的数据都是靶向测序,或者全外测序的数据.对数据的覆盖深度及靶向捕获效率的评估成为了数据质量监控中必不可少的一环. 以前都是用samtools depth 算出单碱基的深度后,用perl来进行深 ...
- CentOs 版本名字说明
What images are in this directory CentOS-6.3-x86_64-netinstall.iso This is the network install and r ...
- Python 把两个列表遍历为一个
两个list, 有对应关系,希望同时完成遍历 用迭代器迭代的方法也不是不可以,python提供了更直观的方法: 可以使用zip把两个list打包 , 类似: list1 = [1,2,3,4] lis ...
- mac下使用clion构建boost库
mac下使用clion构建boost库 使用brew install boost 完成后发现boost被安装在在/usr/local/Cellar/boost下 jetbrain给出的指导意见 htt ...
- 学习MVC中出现的一个BUG
BUG描述:No Entity Framework provider found for the ADO.NET provider with invariant name 'System.Data.S ...