hdu3041 单调队列优化dp

来源:互联网 发布:超星网络教学平台 编辑:程序博客网 时间:2024/06/05 17:06

https://vjudge.net/solution/2611950 上师兄的代码。。
这个地方的维护的是单调递减的队列,,
这样

买进: f[i][j]=max(f[i-W-1][k]-(j-k)*e[i].ap,f[i][j])。在这里j-e[i].as

#include<iostream>#include<algorithm>#include<cstdio>#include<string>#include<queue>#include<cstring>using namespace std;#define sf scanf#define pf printf#define mem(a,b) memset(a,b,sizeof(a));#define rep(i,a,b) for(int i=(a);i<=(b);++i)#define M 200020#define mod 998244353#define ULL unsigned long long#define LL long long#define inf 0x3f3f3f3f#define ls (rt<<1)#define rs (ls|1)#define md ((ll+rr)>>1)#define mxn  2020//2017年08月09日08:09:06   10min//2017年08月09日08:25:16  10minint  dp[mxn][mxn];int ap[mxn],bp[mxn],as[mxn],bs[mxn];int t,P,w;void read(){    sf("%d%d%d",&t,&P,&w);    rep(i,1,t)sf("%d%d%d%d",&ap[i],&bp[i],&as[i],&bs[i]);    rep(i,0,t)rep(j,0,P)dp[i][j]=-inf;}int main(){    freopen("in.txt","r",stdin);    int T ;sf("%d",&T);    while(T--){        read();        for(int i=1;i<=t;++i){            for(int j=0;j<=P;++j)                dp[i][j]=max(dp[i-1][j],dp[i][j]);            if(i<=w+1){                for(int j=0;j<=min(as[i],P);++j)                    dp[i][j]=max(dp[i][j],-j*as[i]);                continue;            }            int u=i-w-1;            deque<int>q;            for(int j=0;j<=P;++j){                while(!q.empty()&&dp[u][q.back()]+q.back()*ap[i]<dp[u][j]+j*ap[i])q.pop_back();                q.push_back(j);                while(!q.empty()&&q.front()+as[i]<j)q.pop_front();                if(!q.empty())                    dp[i][j]=max(dp[i][j],dp[u][q.front()]-(j-q.front())*ap[i]);            }            while(!q.empty())q.pop_front();            for(int j=P;j>=0;--j){                while(!q.empty()&&dp[u][q.back()]+q.back()*bp[i]<dp[u][j]+j*bp[i])q.pop_back();                q.push_back(j);                while(!q.empty()&&q.front()-bs[i]>j)q.pop_front();                if(!q.empty())                    dp[i][j]=max(dp[i][j],dp[u][q.front()]+(q.front()-j)*bp[i]);            }        }        int ans=0;        rep(i,0,P)ans=max(ans,dp[t][i]);        pf("%d\n",ans);    }}
原创粉丝点击