【题目大意】
一人预测了未来n天的股市行情,允许他有的最大股票数是Maxp,交易必须至少间隔W天,到第i天,他可以买进当天的股票,ap[i]一注,最多买as[i]注,可以在当天卖手里的股票,bp[i]一注,最多卖bs[i]注,问这样n天后他最多获利多少。
【分析】
dp做多点,方程还是很好想的,dp[i][j]: 到第i天有股票j拥有的最大获利,显然第i天要么什么都不做,要么买股票,要么卖股票,dp[i][j]由三个状态转移过来:
dp[i][j]= max{ dp[i-1][j];
dp[i-W-1][k] - ap[i] * (j-k);
dp[i-W-1][k] + bp[i]* (k-j);
}
然后就是优化。 有这种要遍历第三维k的一般都要考虑是否能用到单调队列优化,关键是变形 t=dp[i-W-1][k]+ap[i]*k,这样t仅与k有关,而剩下的ap[i]*j仅与i,j有关是个定值,t在遍历j的时候就可以依次求出,且保存到一个单调递减队列,这样每次取队首元素就是最优结果了,时间复杂度很低。不想写太多了,网上翻了很多,我挑了个十分好的,贴下,代码最好自己能写。 我的代码风格是初始化head=0,rear=0,rear忘记-1了,查错许久。。。
【代码】
/*2011-07-07 16:21:23 Accepted 3401 281MS 16040K 2207 B C++*/
#define maxn 2005
void up_max(int &x,int y){if(x<y)x=y;}
int dp[maxn][maxn];
int ap[maxn],bp[maxn],as[maxn],bs[maxn];
int que[maxn],pos[maxn];
int main()
{
int T,n,maxp,W,i,j,k;
cin>>T;
while(T--)
{
cin>>n>>maxp>>W;
W++;
for(i=1;i<=n;i++)
scanf("%d%d%d%d",ap+i,bp+i,as+i,bs+i);
for(i=1;i<=n;i++)
for(j=0;j<=maxp;j++)
dp[i][j]= -maxint;
//前W天要么无操作,要么只能买股票;
for(i=1;i<=W;i++)
for(j=0;j<=as[i];j++)
dp[i][j]= -ap[i]*j; //负号啊!!!
for(i=2;i<=n;i++){
//第i天什么都不做;
for(j=0;j<=maxp;j++)
up_max(dp[i][j],dp[i-1][j]);
if(i<=W) continue; //前W天的也必须更新;
//第i天买股票;
int head=0,rear=0;
for(j=0;j<=maxp;j++){
int t= dp[i-W][j]+ap[i]*j;
while(head<rear&&t>que[rear-1])
rear--;
que[rear]= t;
pos[rear++]= j;
while(head<rear&&j-pos[head]>as[i])
head++;
up_max(dp[i][j],que[head]-ap[i]*j);
}
//第i天卖股票, 逆序做dp;
head=0, rear=0;
for(j=maxp;j>=0;j--){
int t= dp[i-W][j]+bp[i]*j;
while(head<rear&&t>que[rear-1])
rear--;
que[rear]= t;
pos[rear++]= j;
while(head<rear&&pos[head]-j>bs[i])
head++;
up_max(dp[i][j],que[head]-bp[i]*j);
}
}
printf("%d\n",*max_element(dp[n],dp[n]+maxp+1));
}
}
44CQ6aKY55uu5aSn5oSP44CRCuS4gOS6uumihOa1i+S6huacquadpW7lpKnnmoTogqHluILooYzmg4XvvIzlhYHorrjku5bmnInnmoTmnIDlpKfogqHnpajmlbDmmK9NYXhw77yM5Lqk5piT5b+F6aG76Iez5bCR6Ze06ZqUV+Wkqe+8jOWIsOesrGnlpKnvvIzku5blj6/ku6XkubDov5vlvZPlpKnnmoTogqHnpajvvIxhcFtpXeS4gOazqO+8jOacgOWkmuS5sGFzW2ld5rOo77yM5Y+v5Lul5Zyo5b2T5aSp5Y2W5omL6YeM55qE6IKh56Wo77yMYnBbaV3kuIDms6jvvIzmnIDlpJrljZZic1tpXeazqO+8jOmXrui/meagt27lpKnlkI7ku5bmnIDlpJrojrfliKnlpJrlsJHjgIIKCuOAkOWIhuaekOOAkQpkcOWBmuWkmueCue+8jOaWueeoi+i/mOaYr+W+iOWlveaDs+eahO+8jGRwW2ldW2pdOiDliLDnrKxp5aSp5pyJ6IKh56WoauaLpeacieeahOacgOWkp+iOt+WIqe+8jOaYvueEtuesrGnlpKnopoHkuYjku4DkuYjpg73kuI3lgZrvvIzopoHkuYjkubDogqHnpajvvIzopoHkuYjljZbogqHnpajvvIxkcFtpXVtqXeeUseS4ieS4queKtuaAgei9rOenu+i/h+adpe+8mgoKZHBbaV1bal09IG1heHsgZHBbaS0xXVtqXTsKCiAgICAgICAgICAgICAgICBkcFtpLVctMV1ba10gLSBhcFtpXSAqIChqLWspOyAKCiAgICAgICAgICAgICAgICBkcFtpLVctMV1ba10gKyBicFtpXSogKGstaik7CgogICAgICAgICAgICAgIH0KCueEtuWQjuWwseaYr+S8mOWMluOAgiDmnInov5nnp43opoHpgY3ljobnrKzkuInnu7Rr55qE5LiA6Iis6YO96KaB6ICD6JmR5piv5ZCm6IO955So5Yiw5Y2V6LCD6Zif5YiX5LyY5YyW77yM5YWz6ZSu5piv5Y+Y5b2iIHQ9ZHBbaS1XLTFdW2tdK2FwW2ldKmvvvIzov5nmoLd05LuF5LiOa+acieWFs++8jOiAjOWJqeS4i+eahGFwW2ldKmrku4XkuI5p77yMauacieWFs+aYr+S4quWumuWAvO+8jHTlnKjpgY3ljoZq55qE5pe25YCZ5bCx5Y+v5Lul5L6d5qyh5rGC5Ye677yM5LiU5L+d5a2Y5Yiw5LiA5Liq5Y2V6LCD6YCS5YeP6Zif5YiX77yM6L+Z5qC35q+P5qyh5Y+W6Zif6aaW5YWD57Sg5bCx5piv5pyA5LyY57uT5p6c5LqG77yM5pe26Ze05aSN5p2C5bqm5b6I5L2O44CC5LiN5oOz5YaZ5aSq5aSa5LqG77yM572R5LiK57+75LqG5b6I5aSa77yM5oiR5oyR5LqG5Liq5Y2B5YiG5aW955qE77yM6LS05LiL77yM5Luj56CB5pyA5aW96Ieq5bex6IO95YaZ44CCICDmiJHnmoTku6PnoIHpo47moLzmmK/liJ3lp4vljJZoZWFkPTDvvIxyZWFyPTDvvIxyZWFy5b+Y6K6wLTHkuobvvIzmn6XplJnorrjkuYXjgILjgILjgIIKCuOAkOS7o+eggeOAkQovKjIwMTEtMDctMDcgMTY6MjE6MjMJQWNjZXB0ZWQgMzQwMSAyODFNUyAxNjA0MEsJMjIwNyBCCUMrKyovCiNkZWZpbmUgbWF4biAyMDA1CnZvaWQgdXBfbWF4KGludCAmeCxpbnQgeSl7aWYoeDx5KXg9eTt9CmludCBkcFttYXhuXVttYXhuXTsKaW50IGFwW21heG5dLGJwW21heG5dLGFzW21heG5dLGJzW21heG5dOwppbnQgcXVlW21heG5dLHBvc1ttYXhuXTsKaW50IG1haW4oKQp7CiAgICBpbnQgVCxuLG1heHAsVyxpLGosazsKICAgIGNpbj4+VDsKICAgIHdoaWxlKFQtLSkKICAgIHsKICAgICAgICBjaW4+Pm4+Pm1heHA+Plc7CiAgICAgICAgVysrOwogICAgICAgIGZvcihpPTE7aTw9bjtpKyspCiAgICAgICAgICAgIHNjYW5mKCIlZCVkJWQlZCIsYXAraSxicCtpLGFzK2ksYnMraSk7CiAgICAgICAgZm9yKGk9MTtpPD1uO2krKykKICAgICAgICAgICAgZm9yKGo9MDtqPD1tYXhwO2orKykKICAgICAgICAgICAgICAgIGRwW2ldW2pdPSAtbWF4aW50OwogICAgICAgIC8v5YmNV+WkqeimgeS5iOaXoOaTjeS9nO+8jOimgeS5iOWPquiDveS5sOiCoeelqO+8myAKICAgICAgICBmb3IoaT0xO2k8PVc7aSsrKQogICAgICAgICAgICBmb3Ioaj0wO2o8PWFzW2ldO2orKykKICAgICAgICAgICAgICAgIGRwW2ldW2pdPSAtYXBbaV0qajsgLy/otJ/lj7fllYrvvIHvvIHvvIEgCgogICAgICAgIGZvcihpPTI7aTw9bjtpKyspewogICAgICAgICAgICAvL+esrGnlpKnku4DkuYjpg73kuI3lgZrvvJsgCiAgICAgICAgICAgIGZvcihqPTA7ajw9bWF4cDtqKyspCiAgICAgICAgICAgICAgICB1cF9tYXgoZHBbaV1bal0sZHBbaS0xXVtqXSk7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZihpPD1XKSBjb250aW51ZTsgLy/liY1X5aSp55qE5Lmf5b+F6aG75pu05paw77ybIAogICAgICAgICAgICAvL+esrGnlpKnkubDogqHnpajvvJsKICAgICAgICAgICAgaW50IGhlYWQ9MCxyZWFyPTA7CiAgICAgICAgICAgIGZvcihqPTA7ajw9bWF4cDtqKyspewogICAgICAgICAgICAgICAgaW50IHQ9IGRwW2ktV11bal0rYXBbaV0qajsKICAgICAgICAgICAgICAgIHdoaWxlKGhlYWQ8cmVhciYmdD5xdWVbcmVhci0xXSkgCiAgICAgICAgICAgICAgICAgICAgcmVhci0tOwogICAgICAgICAgICAgICAgcXVlW3JlYXJdPSB0OwogICAgICAgICAgICAgICAgcG9zW3JlYXIrK109IGo7CiAgICAgICAgICAgICAgICB3aGlsZShoZWFkPHJlYXImJmotcG9zW2hlYWRdPmFzW2ldKQogICAgICAgICAgICAgICAgICAgIGhlYWQrKzsKICAgICAgICAgICAgICAgIHVwX21heChkcFtpXVtqXSxxdWVbaGVhZF0tYXBbaV0qaik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy/nrKxp5aSp5Y2W6IKh56WoLCDpgIbluo/lgZpkcO+8mwogICAgICAgICAgICBoZWFkPTAsIHJlYXI9MDsgCiAgICAgICAgICAgIGZvcihqPW1heHA7aj49MDtqLS0pewogICAgICAgICAgICAgICAgaW50IHQ9IGRwW2ktV11bal0rYnBbaV0qajsKICAgICAgICAgICAgICAgIHdoaWxlKGhlYWQ8cmVhciYmdD5xdWVbcmVhci0xXSkgCiAgICAgICAgICAgICAgICAgICAgcmVhci0tOwogICAgICAgICAgICAgICAgcXVlW3JlYXJdPSB0OwogICAgICAgICAgICAgICAgcG9zW3JlYXIrK109IGo7CiAgICAgICAgICAgICAgICB3aGlsZShoZWFkPHJlYXImJnBvc1toZWFkXS1qPmJzW2ldKSAKICAgICAgICAgICAgICAgICAgICBoZWFkKys7CiAgICAgICAgICAgICAgICB1cF9tYXgoZHBbaV1bal0scXVlW2hlYWRdLWJwW2ldKmopOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHByaW50ZigiJWRcbiIsKm1heF9lbGVtZW50KGRwW25dLGRwW25dK21heHArMSkpOwogICAgfQp9ICAgICAgICAgICAgICAgIA==