trade
时间限制:2000/1000 MS(Java / Others)
内存限制:32768/32768 K(Java / Others)
总提交内容:5395 已接受提交内容:1870
问题描述
最近,
lxhgww
l
x
h
g
w
w
沉迷于股票,他在几天的研究后发现了一些规律。
他预测下一个
T
T
天的股市。在第天,您可以用价格
APi
A
P
i
买入一只股票,或者卖出一只股票以获得
BPi
B
P
i
。
还有一些其他的限制,一个可以在第i天最多买入
ASi
A
S
i
只股票,最多卖出
BSi
B
S
i
只股票。
两个交易日的间隔时间应该超过W天。也就是说,假设您在第i天交易(任何买入或卖出股票被视为交易),下一个交易日必须在第
(i+W+1)
(
i
+
W
+
1
)
天或之后。
更重要的是,任何时候都最多拥有
MaxP
M
a
x
P
股票。
在第一天之前, lxhgww l x h g w w 已经有无限的资金,但没有股票,当然他想从股市赚尽可能多的钱。所以问题出现了,他至多可以赚多少钱?
输入
第一行是整数
t
t
,即案例编号。
每种情况的第一行是三个整数。
(0≤W,T≤2000,1≤MaxP≤2000)
(
0
≤
W
,
T
≤
2000
,
1
≤
M
a
x
P
≤
2000
)
。
接下来的T行分别具有上面提到的四个整数
APi,BPi,ASi,BSi
A
P
i
,
B
P
i
,
A
S
i
,
B
S
i
(1≤BPi≤Δi≤1000,1≤Δi,BSi≤MaxP)
(
1
≤
B
P
i
≤
Δ
i
≤
1000
,
1
≤
Δ
i
,
B
S
i
≤
M
a
x
P
)
。
输出
lxhgww l x h g w w 最赚钱。
示例输入
1
5 2 0
2 1 1 1
2 1 1 1
3 2 1 1
4 3 1 1
5 4 1 1
示例输出
3
解:
这道题比起修剪草坪要有点脑子了,不过还是单调队列优化dp。怎么单调队列?还是要推一波式子:
fi,j=max{fi−w−1,k−(j−k)∗APi} (k<j) f i , j = m a x { f i − w − 1 , k − ( j − k ) ∗ A P i } ( k < j )
fi,j=max{fi−w−1,k+(k−j)∗BPi} (k>j) f i , j = m a x { f i − w − 1 , k + ( k − j ) ∗ B P i } ( k > j )
fi,j=max{fi−1,j} f i , j = m a x { f i − 1 , j }
这里的三个式子前两个把 j j 提出来是可以使用单调队列优化的。因为里与 fi,j f i , j 毫无关系了,就相当于区间求最值。一开始写的时候忘记了第三个转移,想到相邻的两天不会转移,结果忘记不买也是转移。然后初始化初始化了好久,老是有些地方没有初始化。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
struct lxy{
int id;
int x;
};
int f[2005][2005];
int T,n,w,maxp;
int ap,bp,as,bs,ans;
deque <lxy> d;
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&maxp,&w);
for(int i=0;i<=n;i++)
for(int j=0;j<=maxp;j++)
f[i][j]=-0x3f3f3f3f;
for(int i=1;i<=min(w+1,n);i++)
{
scanf("%d%d%d%d",&ap,&bp,&as,&bs);
for(int j=0;j<=min(as,maxp);j++)
f[i][j]=-ap*j;
for(int j=0;j<=maxp;j++)
f[i][j]=max(f[i-1][j],f[i][j]);
}
for(int i=w+2;i<=n;i++)
{
scanf("%d%d%d%d",&ap,&bp,&as,&bs);
while(!d.empty()) d.pop_back();
for(int j=0;j<=maxp;j++)
{
if(!d.empty()&&d.front().id<j-as)
d.pop_front();
while(!d.empty()&&d.back().x<=f[i-w-1][j]+j*ap)
d.pop_back();
lxy p;p.x=f[i-w-1][j]+j*ap;p.id=j;
d.push_back(p);
f[i][j]=max(f[i][j],d.front().x-j*ap);
}
while(!d.empty()) d.pop_back();
for(int j=maxp;j>=0;j--)
{
if(!d.empty()&&d.front().id>j+bs)
d.pop_front();
while(!d.empty()&&d.back().x<=f[i-w-1][j]+j*bp)
d.pop_back();
lxy p;p.x=f[i-w-1][j]+j*bp;p.id=j;
d.push_back(p);
f[i][j]=max(f[i][j],d.front().x-j*bp);
}
for(int j=0;j<=maxp;j++)
f[i][j]=max(f[i-1][j],f[i][j]);
}
printf("%d\n",f[n][0]);
}
}