给定每天的股票买进上限,买进价格,卖出上限,卖出价格,每两次买卖操作中间必须间隔w天,每天最多持有maxp个股票,问n天后最大收益是多少

DP方程显然:

dp[i][j]=max(不买不卖,买入操作,卖出操作)

不买不卖
dp[i][j]=max(dp[i][j],dp[i-1][j])
买
dp[i][j]=max(dp[pre][k]-(j-k)*AP[i])
dp[i][j]+j*AP[i]=max(dp[pre][k]+k*AP[i])
令f(k)=dp[i][k]+k*AP[i]
f(j)=max(f(k)) (j-AS[i]<=k<=j)//经典单调队列
所以dp[i][j]=f(j)-j*AP[i]
卖
dp[i][j]=max(dp[pre][k]+(k-j)*BP[[i])
dp[i][j]+j*BP[i]=max(dp[pre][k]+k*BP[i])
令ff(k)=dp[i][k]+k*AP[i]
ff(j)=max(ff(k)) (j<=k<=j+BS[i])
所以dp[i][j]=ff(j)-j*BP[i]

Note:两个过程要分开写 不然WAWAWA

#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;const int N=2010;const int inf=0x80808080;typedef pair<int,int> PII;int T;int Time,MaxP,W;int ap[N],bp[N],as[N],bs[N];int dp[N][N];PII que[N];int st,ed;int main() {    scanf("%d",&T);    while(T--) {        memset(dp[0],inf,sizeof(dp[0]));        dp[0][0]=0;        scanf("%d%d%d",&Time,&MaxP,&W);        for(int i=1;i<=Time;i++) scanf("%d%d%d%d",&ap[i],&bp[i],&as[i],&bs[i]);        int ans=0;        for(int i=1;i<=Time;i++) {            memcpy(dp[i],dp[i-1],sizeof(dp[i]));            if(i<=W+1) {                for(int j=0;j<=as[i];j++) dp[i][j]=max(dp[i-1][j],-ap[i]*j);                continue;            }            st=ed=0;            int pre=i-W-1;            //buy            for(int j=0;j<=MaxP;j++) {                PII elem=PII(dp[pre][j]+j*ap[i],j);                que[ed++]=elem;                while(ed-st>=1 && que[st].second<j-as[i]) st++;                while(ed-st>=2 && que[ed-1].first>=que[ed-2].first) que[ed-2]=que[ed-1],ed--;                dp[i][j]=max(dp[i][j],que[st].first-j*ap[i]);                ans=max(ans,dp[i][j]);            }            st=ed=0;            //sell            for(int j=MaxP;j>=0;j--) {                PII elem=PII(dp[pre][j]+j*bp[i],j);                que[ed++]=elem;                while(ed-st>=1 && que[st].second>j+bs[i]) st++;                while(ed-st>=2 && que[ed-1].first>=que[ed-2].first) que[ed-2]=que[ed-1],ed--;                dp[i][j]=max(dp[i][j],que[st].first-j*bp[i]);                ans=max(ans,dp[i][j]);            }        }        printf("%d\n",ans);    }    return 0;}



posted @ 2012-08-29 17:12  编程菜菜  阅读(221)  评论(0编辑  收藏  举报