"The main topic"
It is known that the stock bid price for day I is per share of the API, the first day of the stock price is BPi per share (data guarantee for each I, there is API>=BPI), the first day of purchase can only buy ASI shares, a sell at most can only sell BSI shares. The stock Exchange provides for a minimum of W days between two transactions (one day's buy or sell), that is, if a transaction occurs on the first day, the transaction cannot occur from i+1 to i+w days. Meanwhile, at any time, the number of shares in a person's hand cannot exceed Maxp. Before the 1th day, there was a large amount of money (which could be considered unlimited), without any stock, how much money would be earned after T-day?
Ideas
F[I][J] represents the maximum benefit of holding up to J shares in the hands of the first trading day.
1, the previous day does not buy not sell: F[i][j]=max (F[i-1][j],f[i][j])
2, from i-w-1 days buy Shares: F[i][j]=max (f[i-w-1][k]-(j-k) *ap[i],f[i][j])
F[i][j]=max (F[i-w-1][k]+k*ap[i])-j*ap[i]
Make g[i-w-1][k]=f[i-w-1][k]+k*ap[i]→ F[i][j]=max (g[i-w-1][k])-j*ap[i]
3, from i-w-1 days sell shares: F[i][j]=max (f[i-w-1][k]+ (k-j) *bp[i],f[i][j])
F[i][j]=max (F[i-w-1][k]+k*bp[i])-j*bp[i].
Make G ' [i-w-1][k]=f[i-w-1][k]+k*bp[i]→ F[i][j]=max (g ' [i-w-1][k])-j*bp[i]
Because for G[i-w-1][j] and G ' [i-w-1][j] are satisfied: if J1>j2 and G[i-w-1][j1]>g[i-w-1][j2], you do not have to keep g[i-w-1][j2]. So you can use the monotone queue to optimize.
#关于初始化 #f[0][0]=0, for 1~w+1 days, there is only a buy operation, with an initial value of-ap[i]*j.
1#include <iostream>2#include <cstdio>3#include <cstring>4#include <algorithm>5 #definePre i-w-16 #defineINF 0x7fffffff7 using namespacestd;8 Const intmaxn= -+5;9 structnodeTen { One intF,pos; A }; - intt,maxp,w; - intAP[MAXN],BP[MAXN],AS[MAXN],BS[MAXN]; the intF[MAXN][MAXN];//represents the maximum benefit of holding J shares in the hands of the first trading day - node Q[MAXN]; - - voidInit () + { -scanf"%d%d%d",&t,&maxp,&W); + for(intI=1; i<=t;i++) scanf ("%d%d%d%d",&ap[i],&bp[i],&as[i],&bs[i]); A } at - voidDP () - { -Memset (F, -,sizeof(f)); - for(intI=0; i<=w+1; i++) - { in for(intj=0; j<= (min (maxp,as[i)); J + +) -F[i][j]=-ap[i]*j;//indicates that only a buy operation is possible before (w+1) days to } +f[0][0]=0; - for(intI=1; i<=t;i++) the { * for(intj=0; j<=maxp;j++) F[i][j]=max (f[i][j],f[i-1][j]); $ if(pre>0)Panax Notoginseng { - intHead=0, tail=0; the for(intj=0; j<=maxp;j++) + { A intnowf=f[pre][j]+ap[i]*J; the while(Head<tail && q[tail-1].F<NOWF) tail--; +q[tail++]=(node) {nowf,j}; - while(Head<tail && q[head].pos<j-as[i]) head++; $F[i][j]=max (f[i][j],q[head].f-ap[i]*j); $ } - -Head=0, tail=0; the for(intj=maxp;j>=0; j--) - {Wuyi intnowf=f[pre][j]+bp[i]*J; the while(Head<tail && q[tail-1].F<NOWF) tail--; -q[tail++]=(node) {nowf,j}; Wu while(Head<tail && q[head].pos>j+bs[i]) head++; -F[i][j]=max (f[i][j],q[head].f-bp[i]*j); About } $ } - } - } - A voidGetans () + { the intans=-INF; - for(intI=0; i<=maxp;i++) ans=Max (ans,f[t][i]); $printf"%d\n", ans); the } the the intMain () the { - init (); in DP (); the Getans (); the return 0; About}
"Monotone Queue optimization DP" BZOJ1855-[SCOI2010] stock Trading