[SCOI2010]股票交易
2019-06-17 16:12 一只弱鸡丶 阅读(236) 评论(0) 编辑 收藏 举报#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; }