[luogu] P2569 [SCOI2010]股票交易 (单调队列优化)
P2569 [SCOI2010]股票交易
题目描述
最近 \(\text{lxhgww}\) 又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律。
通过一段时间的观察,\(\text{lxhgww}\) 预测到了未来 \(T\) 天内某只股票的走势,第 \(i\) 天的股票买入价为每股 \(AP_i\),第 \(i\) 天的股票卖出价为每股 \(BP_i\)(数据保证对于每个 \(i\),都有 \(AP_i \geq BP_i\)),但是每天不能无限制地交易,于是股票交易所规定第 \(i\) 天的一次买入至多只能购买 \(AS_i\) 股,一次卖出至多只能卖出 \(BS_i\) 股。
另外,股票交易所还制定了两个规定。为了避免大家疯狂交易,股票交易所规定在两次交易(某一天的买入或者卖出均算是一次交易)之间,至少要间隔 \(W\) 天,也就是说如果在第 \(i\) 天发生了交易,那么从第 \(i+1\) 天到第 \(i+W\)天,均不能发生交易。同时,为了避免垄断,股票交易所还规定在任何时间,一个人的手里的股票数不能超过 \(\text{MaxP}\)。
在第 \(1\) 天之前,\(\text{lxhgww}\) 手里有一大笔钱(可以认为钱的数目无限),但是没有任何股票,当然,\(T\) 天以后,\(\text{lxhgww}\) 想要赚到最多的钱,聪明的程序员们,你们能帮助他吗?
输入输出格式
输入格式:
输入数据第一行包括 \(3\) 个整数,分别是 \(T\) ,\(\text{MaxP}\),\(W\)。
接下来 \(T\) 行,第 \(i\) 行代表第 \(i-1\) 天的股票走势,每行 \(4\) 个整数,分别表示 \(AP_i,\ BP_i,\ AS_i,\ BS_i\)。
输出格式:
输出数据为一行,包括 \(1\) 个数字,表示 \(\text{lxhgww}\) 能赚到的最多的钱数。
输入输出样例
输入样例#1: 复制
5 2 0
2 1 1 1
2 1 1 1
3 2 1 1
4 3 1 1
5 4 1 1
输出样例#1: 复制
3
说明
对于 \(30\%\) 的数据,\(0\leq W<T\leq 50,1\leq\text{MaxP}\leq50\)
对于 \(50\%\) 的数据,\(0\leq W<T\leq 2000,1\leq\text{MaxP}\leq50\)
对于 \(100\%\) 的数据,\(0\leq W<T\leq 2000,1\leq\text{MaxP}\leq2000\)
对于所有的数据,\(1\leq BP_i\leq AP_i\leq 1000,1\leq AS_i,BS_i\leq\text{MaxP}\)
题解
可以说下面这篇博客写的算是非常好了。
sooke关于本题的题解
Code
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
const int N=3e3+5;
int f[N][N];
int as[N],ap[N],bs[N],bp[N];
int n,maxp,w,q[N];
int read(){
int x=0,w=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*w;
}
int main(){
n=read();maxp=read();w=read();
memset(f,128,sizeof(f));
for(int i=1;i<=n;i++){
ap[i]=read();bp[i]=read();
as[i]=read();bs[i]=read();
for(int j=0;j<=as[i];j++)
f[i][j]=-j*ap[i];
}
for(int i=1;i<=n;i++){
for(int j=0;j<=maxp;j++)
f[i][j]=max(f[i-1][j],f[i][j]);
if(i<=w)continue;
int h=1,t=0;
for(int j=0;j<=maxp;j++){
while(h<=t&&q[h]<j-as[i])h++;
while(h<=t&&f[i-w-1][q[t]]+q[t]*ap[i]<=f[i-w-1][j]+j*ap[i])t--;
q[++t]=j; if(h<=t) f[i][j]=max(f[i][j],f[i-w-1][q[h]]+q[h]*ap[i]-ap[i]*j);
}h=1;t=0;
for(int j=maxp;j>=0;j--){
while(h<=t&&q[h]>j+bs[i])h++;
while(h<=t&&f[i-w-1][q[t]]+q[t]*bp[i]<=f[i-w-1][j]+j*bp[i])t--;
q[++t]=j; if(h<=t) f[i][j]=max(f[i][j],f[i-w-1][q[h]]+q[h]*bp[i]-bp[i]*j);
}
}
cout<<f[n][0]<<endl;
return 0;
}
[luogu] P2569 [SCOI2010]股票交易 (单调队列优化)的更多相关文章
- LUOGU P2569 [SCOI2010]股票交易(单调队列优化dp)
传送门 解题思路 不难想一个\(O(n^3)\)的\(dp\),设\(f_{i,j}\)表示第\(i\)天,手上有\(j\)股的最大收益,因为这个\(dp\)具有单调性,所以\(f_i\)可以贪心的直 ...
- 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只股票时,所赚 ...
- 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 ...
- 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\{ ...
- Luogu P2569 [SCOI2010] 股票交易
此题链接到dp常见优化方法 开始的时候被纪念品误导,以为是多支股票,后来发现事情不妙: 这道题知道的是某一只股票的走势: \(Solution\): \(70pts\): 设\(f[i][j]\)表示 ...
- BZOJ1855 股票交易 单调队列优化 DP
描述 某位蒟佬要买股票, 他神奇地能够预测接下来 T 天的 每天的股票购买价格 ap, 股票出售价格 bp, 以及某日购买股票的上限 as, 某日出售股票上限 bs, 并且每次股票交 ♂ 易 ( 购 ...
随机推荐
- python基础:局部变量--全局变量的使用
局部变量: 使用原则:仅在本函数内部使用的变量,其他函数无法使用本函数的变量 代码: def function1(): a = 2 #定义一个局部变量 print(a) def function2() ...
- Servlet过滤器和监听器知识总结
Servlet过滤器是 Servlet 程序的一种特殊用法,主要用来完成一些通用的操作,如编码的过滤.判断用户的登录状态.过滤器使得Servlet开发者能够在客户端请求到达 Servlet资源之前被截 ...
- 洛谷 U5737 纸条
U5737 纸条 题目背景 明明和牛牛是一对要好的朋友,他们经常上课也想讲话,但是他们的班级是全校纪律最好的班级,所以他们只能通过传纸条的方法来沟通.但是他们并不能保证每次传纸条老师都无法看见,所以他 ...
- POJ 1944
明天补上... 这道题的思路确实很精致.考虑到连的边肯定不会是一个环,所以至少有一个断点.于是,可以枚举这个断点.断点一确定,那么连边的走向也就确定了.用D[i]表示由i开始可以到达的最远点即可.对于 ...
- osEye.Net:离别是为了将来的重逢
这一时刻已经成为osEye历史..... 在热心网友的关怀和鼓励之下,osEye.net将继续运行着,感谢你们陪伴osEye一起走过.... 与你相知相恋已经有4个年头了,你的成长到成熟都让我历历在目 ...
- android 分享到QQ空间的全部操作
http://wiki.open.qq.com/wiki/mobile/SDK下载 <!-- QZone分享必须加上以下两个activity --> &l ...
- 通达OA 小飞鱼工作流在线培训教程(一)HTML基础介绍
应一些刚接触工作流设计朋友的要求,这里开设一个系列教程,对通达OA工作流设计相关的内容做个介绍.方便解决一些日常经常出现的问题,希望对刚刚接触这部分工作的朋友能够有些帮助. 工作流设计须要多方面的知识 ...
- POJ - 3257 Cow Roller Coaster (背包)
题目大意:要用N种材料建一条长为L的路,如今给出每种材料的长度w.起始地点x.发费c和耐久度f 问:在预算为B的情况下,建好这条路的最大耐久度是多少 解题思路:背包问题 dp[i][j]表示起始地点为 ...
- vi 调到第一行,或最后一行
用vi命令打开文件直接跳到最后一行的方法如下: :$ 跳到文件最后一行 :0或:1 跳到文件第一行 或 另外一组命令: gg 跳到文件第一行 Shift + g 跳到文件最后一行
- SAN和NAS
SAN针对海量.面向数据块的数据传输,而NAS则提供文件级的数据访问功能. SAN和NAS都基于开放的.业界标准的网络协议:用于SAN的光纤通道协议和用于NAS的网络协议(如TCP/IP). SAN的 ...