股票交易(DP+单调队列优化)
题目描述
最近lxhgww又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律。
通过一段时间的观察,lxhgww预测到了未来T天内某只股票的走势,第i天的股票买入价为每股APi,第i天的股票卖出价为每股BPi(数据保证对于每个i,都有APi>=BPi),但是每天不能无限制地交易,于是股票交易所规定第i天的一次买入至多只能购买ASi股,一次卖出至多只能卖出BSi股。
另外,股票交易所还制定了两个规定。为了避免大家疯狂交易,股票交易所规定在两次交易(某一天的买入或者卖出均算是一次交易)之间,至少要间隔W天,也就是说如果在第i天发生了交易,那么从第i+1天到第i+W天,均不能发生交易。同时,为了避免垄断,股票交易所还规定在任何时间,一个人的手里的股票数不能超过MaxP。
在第1天之前,lxhgww手里有一大笔钱(可以认为钱的数目无限),但是没有任何股票,当然,T天以后,lxhgww想要赚到最多的钱,聪明的程序员们,你们能帮助他吗?
输入输出格式
输入格式:
输入数据第一行包括3个整数,分别是T,MaxP,W。(0<=W<T<=2000,1<=MaxP<=2000)
接下来T行,第i行代表第i-1天的股票走势,每行4个整数,分别表示APi,BPi,ASi,BSi。(1<=BPi<=APi<=1000,1<=ASi,BSi<=MaxP)
输出格式:
输出数据为一行,包括1个数字,表示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
题目分析:
dp[i][j]代表第i天有j股票数的赚的最多的钱。递推关系分三类:
1.不买不卖 则是dp[i-1][j];
2.买后手里有k,则是dp[i-w-1][k]-(j-k)*ap[i];
3.卖后还有k,则是dp[i-w-1][k]+(k-j)*bp[i];
首先循环i,j是必要的,但是还要枚举买卖多少,复杂度显然不够,因此用单调队列优化。
#include <bits/stdc++.h>
using namespace std;
const int N=;
int ap[N],bp[N],as[N],bs[N];
int dp[N][N],qu[N];
int main()
{
int n,maxp,w;
scanf("%d%d%d",&n,&maxp,&w);
for(int i=;i<=n;i++)
scanf("%d%d%d%d",&ap[i],&bp[i],&as[i],&bs[i]);
memset(dp,-0x7f,sizeof dp);
for(int i=;i<=n;i++) dp[i][]=;
for(int i=;i<=n;i++)
{
for(int j=;j<=as[i];j++) dp[i][j]=-ap[i]*j;
for(int j=maxp;j>=;j--) dp[i][j]=max(dp[i][j],dp[i-][j]);
if(i-w->=)
{
int head=,tail=;
for(int j=;j<=maxp;j++)
{
while(head<=tail&&qu[head]<j-as[i]) head++;//买入大于sa[i]的出队
while(head<=tail&&dp[i-w-][j]+ap[i]*j>=dp[i-w-][qu[tail]]+ap[i]*qu[tail]) tail--;
qu[++tail]=j;
if(head<=tail) dp[i][j]=max(dp[i][j],dp[i-w-][qu[head]]-ap[i]*j+ap[i]*qu[head]);
}
head=,tail=;
for(int j=maxp;j>=;j--)
{
while(head<=tail&&qu[head]>j+bs[i]) head++;//卖出大于bs[i]的出队
while(head<=tail&&dp[i-w-][j]+bp[i]*j>=dp[i-w-][qu[tail]]+bp[i]*qu[tail]) tail--;
qu[++tail]=j;
if(head<=tail) dp[i][j]=max(dp[i][j],dp[i-w-][qu[head]]-bp[i]*j+bp[i]*qu[head]);
}
}
}
int ans=;
for(int i=;i<=maxp;i++)
ans=max(ans,dp[n][i]);
printf("%d\n",ans);
return ;
}
股票交易(DP+单调队列优化)的更多相关文章
- P2569 [SCOI2010]股票交易 dp 单调队列优化
LINK:股票交易 题目确实不算难 但是坑点挺多 关于初值的处理问题我就wa了两次. 所以来谢罪. 由于在手中的邮票的数量存在限制 且每次买入卖出也有限制. 必然要多开一维来存每天的邮票数量. 那么容 ...
- [poj3017] Cut the Sequence (DP + 单调队列优化 + 平衡树优化)
DP + 单调队列优化 + 平衡树 好题 Description Given an integer sequence { an } of length N, you are to cut the se ...
- 2018.09.10 bzoj1855: [Scoi2010]股票交易(单调队列优化dp)
传送门 单调队列优化dp好题. 有一个很明显的状态设置是f[i][j]表示前i天完剩下了j分股票的最优值. 显然f[i][j]可以从f[i-w-1][k]转移过来. 方程很好推啊. 对于j<kj ...
- 【Luogu】P2569股票交易(单调队列优化DP)
题目链接 首先这题可以肯定的是朴素DP秒出.然后单调队列优化因为没接触过所以不会emmm 而且脑补没补出来 坐等四月省选倒数第一emmm 心态爆炸,偷懒放题解链接 #include<cstdio ...
- [SCOI2010] 股票交易 (单调队列优化dp)
题目描述 最近lxhgww又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww预测到了未来T天内某只股票的走势,第i天的股票买入价为每股APi, ...
- 股票交易 (单调队列优化DP)
股票交易 $ solution: $ 这道题以前就写了,题目很好,但自己没有发题解,来补一篇: 首先,题目出得很有迷惑性,但我们不难想到状态要设天数,和自己手上的股票数目(因为这两个就是充要信息).而 ...
- BZOJ1855 [Scoi2010]股票交易 【单调队列优化dp】
题目链接 BZOJ1855 题解 设\(f[i][j]\)表示第\(i\)天结束时拥有\(j\)张股票时的最大收益 若\(i \le W\),显然在这之前不可能有交易 \[f[i][j] = max\ ...
- 1023: [SHOI2008]cactus仙人掌图(DP+单调队列优化)
这道题吗= =首先解决了我多年以来对仙人掌图的疑问,原来这种高大上的东西原来是这个啊= = 然后,看到这种题,首先必须的就是缩点= = 缩点完之后呢,变成在树上找最长路了= =直接树形dp了 那么那些 ...
- Codeforces 1077F2 Pictures with Kittens (hard version)(DP+单调队列优化)
题目链接:Pictures with Kittens (hard version) 题意:给定n长度的数字序列ai,求从中选出x个满足任意k长度区间都至少有一个被选到的最大和. 题解:数据量5000, ...
随机推荐
- webservice、soap、wsdl
搜集了一些关于webservice.soap.wsdl的基本知识,解决工作中遇到的疑问 一 .什么是webservice(用你的话描述webservice)?在什么时候用webservice(webs ...
- NullPointerException检测
APET-NPE插件工作原理 android应用程序编译的过程如下: 从图中,我们可以看出,app编译大致经历了四大阶段:java source files -> .class files -& ...
- 抓取GridView "编辑"模式下,TextBox修改后的数值
[FAQ]抓取GridView "编辑"模式下,TextBox修改后的数值 -- ASP.NET专题实务「上集」Ch.10 抓取GridView "编辑"模式下 ...
- Codeforces Round #321 (Div. 2) E Kefa and Watch (线段树维护Hash)
E. Kefa and Watch time limit per test 1 second memory limit per test 256 megabytes input standard in ...
- UVA 1616 Caravan Robbers 商队抢劫者(二分)
x越大越难满足条件,二分,每次贪心的选区间判断是否合法.此题精度要求很高需要用long double,结果要输出分数,那么就枚举一下分母,然后求出分子,在判断一下和原来的数的误差. #include& ...
- Android颜色选择器介绍
使用Android的颜色选择器可以让我们的view在不同状态下显示不同的颜色. 1.Android中ListView 选择某项改变该行字体颜色 2.文件位置 res/color/filename.xm ...
- BigDecimal and double
BigDecimal类 对于不需要任何准确计算精度的数字可以直接使用float或double,但是如果需要精确计算的结果,则必须使用BigDecimal类,而且使用BigDecimal类也可以进行大数 ...
- ovs的学习
本来编辑好了的, 结果忘了保存, 坑爹,直接把人家的网址贴上来吧 http://blog.chinaunix.net/uid-20737871-id-4333314.html 昨天遇到一个问题(虚拟机 ...
- Bootstrap历练实例:默认的进度条
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...
- UIKeyboardType
typedef NS_ENUM(NSInteger, UIKeyboardType) { UIKeyboardTypeDefault, // Default type for the current ...