版权声明:转载请附带链接或评论 https://blog.csdn.net/corsica6/article/details/82356503
传送门:bzoj1855
题解
设 为第 天结束,手里有 股股票的最大利益,对于第 天的情况,分四种情况讨论:
- 净买入 股,
- 不买不卖,
- 在原来的基础上买入: ,
- 在原来的基础上卖出:
四种情况取 转移即可。
由于对于特定的
,
是单调不下降的,所以简化后两个转移式为:
单调队列优化即可。
代码
#include<bits/stdc++.h>
#define gc getchar()
#define si isdigit(c)
#define RI register
using namespace std;
const int N=2020;
int n,m,w,ap,bp,as,bs;
int q[N],l,r,f[N][N],ans;
char c;
inline void rd(int &x)
{
c=gc;x=0;int f=0;
for(;!si;c=gc) if(c=='-') f=1;
for(;si;c=gc) x=x*10+(c^48);
if(f) x=-x;
}
int main(){
RI int i,j;
memset(f,128,sizeof(f));
rd(n);rd(m);rd(w);
for(i=1;i<=n;++i){
rd(ap);rd(bp);rd(as);rd(bs);
for(j=0;j<=as;++j) f[i][j]=-j*ap;
for(j=0;j<=m;++j) f[i][j]=max(f[i][j],f[i-1][j]);
if(i<=w) continue;
l=1,r=0;
for(j=0;j<=m;++j){
for(;l<=r && q[l]<j-as;++l);
for(;l<=r && f[i-w-1][q[r]]+q[r]*ap<=f[i-w-1][j]+j*ap;--r);
q[++r]=j;
if(l<=r) f[i][j]=max(f[i][j],f[i-w-1][q[l]]+(q[l]-j)*ap);
}
l=1,r=0;
for(j=m;j>=0;--j){
for(;l<=r && q[l]>j+bs;++l);
for(;l<=r && f[i-w-1][q[r]]+q[r]*bp<=f[i-w-1][j]+j*bp;--r);
q[++r]=j;
if(l<=r) f[i][j]=max(f[i][j],f[i-w-1][q[l]]+(q[l]-j)*bp);
}
}
ans=-2e9;
for(i=0;i<=m;++i) ans=max(ans,f[n][i]);
printf("%d\n",ans);
}