传送门:
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
using namespace std;
#define ll long long
#define re register
const int N=1e6+10;
inline void read(int &a)
{
a=0;
int d=1;
char ch;
while(ch=getchar(),ch>'9'||ch<'0')
if(ch=='-')
d=-1;
a=ch^48;
while(ch=getchar(),ch>='0'&&ch<='9')
a=(a<<3)+(a<<1)+(ch^48);
a*=d;
}
int f[2005][2005],q[2005];///第一维天数,第二维持有股数
int main()
{
int n,m,w;
read(n);
read(m);
read(w);
memset(f,128,sizeof(f));
for(re int i=1;i<=n;i++)
{
int ap,bp,as,bs;
read(ap),read(bp),read(as),read(bs);
for(re int j=0;j<=m&&j<=as;j++)
f[i][j]=-j*ap;///无股买入
for(re int j=0;j<=m;j++)
f[i][j]=max(f[i][j],f[i-1][j]);///不买不卖
if(i>w)///有股买入+卖出,因为一次交易后有w天不能交易,所以i>w才能做
{
int h,t;
h=1,t=1;
for(re int j=0;j<=m;j++)
{
while(h<t&&q[h]<j-as)
h++;
while(h<t&&f[i-w-1][q[t-1]]+q[t-1]*ap<=f[i-w-1][j]+j*ap)
t--;
q[t++]=j;
if(h<t)
f[i][j]=max(f[i][j],f[i-w-1][q[h]]+q[h]*ap-j*ap);
}
h=1,t=1;
for(re int j=m;j>=0;j--)
{
while(h<t&&q[h]>j+bs)
h++;
while(h<t&&f[i-w-1][q[t-1]]+q[t-1]*bp<=f[i-w-1][j]+j*bp)
t--;
q[t++]=j;
if(h<t)
f[i][j]=max(f[i][j],f[i-w-1][q[h]]+q[h]*bp-j*bp);
}
}
}
printf("%d",f[n][0]);
return 0;
}