携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第30天,点击查看活动详情
[SCOI2010]股票交易
题目描述
最近 又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律。
通过一段时间的观察, 预测到了未来 天内某只股票的走势,第 天的股票买入价为每股 ,第 天的股票卖出价为每股 (数据保证对于每个 ,都有 ),但是每天不能无限制地交易,于是股票交易所规定第 天的一次买入至多只能购买 股,一次卖出至多只能卖出 股。
另外,股票交易所还制定了两个规定。为了避免大家疯狂交易,股票交易所规定在两次交易(某一天的买入或者卖出均算是一次交易)之间,至少要间隔 天,也就是说如果在第 天发生了交易,那么从第 天到第 天,均不能发生交易。同时,为了避免垄断,股票交易所还规定在任何时间,一个人的手里的股票数不能超过 。
在第 天之前, 手里有一大笔钱(可以认为钱的数目无限),但是没有任何股票,当然, 天以后, 想要赚到最多的钱,聪明的程序员们,你们能帮助他吗?
输入格式
输入数据第一行包括 个整数,分别是 ,,。
接下来 行,第 行代表第 天的股票走势,每行 个整数,分别表示 。
输出格式
输出数据为一行,包括 个数字,表示 能赚到的最多的钱数。
样例 #1
样例输入 #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
提示
对于 的数据,
对于 的数据,
对于 的数据,
对于所有的数据,
#include <cstdio>
#include <algorithm>
using namespace std;
const int INF=2000000000;
int t,maxp,w,ap[2010],bp[2010],as[2010],bs[2010],d[2010][2010],q[2010],p[2010],head,tail;
inline int read(){
int num=0,k=1; char c=getchar();
while(c>'9' || c<'0') k=(c=='-')?0:k,c=getchar();
while(c>='0' && c<='9') num=num*10+c-'0',c=getchar();
return k?num:-num;
}
int main(){
t=read(); maxp=read(); w=read();
for(int i=1;i<=maxp;i++) d[0][i]=-INF;
for(int i=1;i<=t;i++) ap[i]=read(),bp[i]=read(),as[i]=read(),bs[i]=read();
for(int cur=1,las;cur<=t;cur++){
las=max(0,cur-w-1);
for(int i=0;i<=maxp;i++) d[cur][i]=d[cur-1][i];
head=1; tail=0;
for(int i=0;i<=maxp;i++){
while(head<=tail && q[tail]<=d[las][i]+i*ap[cur]) tail--;
q[++tail]=d[las][i]+i*ap[cur]; p[tail]=i;
while(head<=tail && i-p[head]>as[cur]) head++;
d[cur][i]=max(d[cur][i],q[head]-i*ap[cur]);
}
head=1; tail=0;
for(int i=maxp;i>=0;i--){
while(head<=tail && q[tail]<=d[las][i]+i*bp[cur]) tail--;
q[++tail]=d[las][i]+i*bp[cur]; p[tail]=i;
while(head<=tail && p[head]-i>bs[cur]) head++;
d[cur][i]=max(d[cur][i],q[head]-i*bp[cur]);
}
}
printf("%d",d[t][0]);
return 0;
}