[CF480D]Parcels

来源:互联网 发布:初学者编程 编辑:程序博客网 时间:2024/06/05 17:06

题目描述

http://codeforces.com/contest/480/problem/D

DP

区间DP是可行的,但是是4*n^2*S,亲测过不了。
然后n^2*S的看这个
http://blog.csdn.net/keshuai19940722/article/details/40720965
区间DP:

#include<cstdio>#include<algorithm>#define fo(i,a,b) for(i=a;i<=b;i++)#define fd(i,a,b) for(i=a;i>=b;i--)#define max(a,b) (a>b?a:b)using namespace std;const int maxn=1000+10;int f[maxn][maxn*2],g[maxn][maxn*2],dis[maxn][maxn],p[maxn][maxn*2];int a[maxn],b[maxn],w[maxn],s[maxn],v[maxn],sum[maxn],num[maxn];int h[maxn],go[maxn],next[maxn],c[maxn*2];int i,j,k,l,x,y,t,n,m,tot,top,ans,mx,mi;void add(int x,int y){    go[++tot]=y;    next[tot]=h[x];    h[x]=tot;}int main(){    scanf("%d%d",&n,&m);    mi=2*n;    fo(i,1,n){        scanf("%d%d%d%d%d",&a[i],&b[i],&w[i],&s[i],&v[i]);        a[i]++;b[i]++;        c[++top]=a[i];    }    sort(c+1,c+top+1);    top=unique(c+1,c+top+1)-c-1;    fo(i,1,n) a[i]=lower_bound(c+1,c+top+1,a[i])-c;    top=0;    fo(i,1,n) c[++top]=b[i];    top=unique(c+1,c+top+1)-c-1;    fo(i,1,n) b[i]=lower_bound(c+1,c+top+1,b[i])-c;    fo(i,1,n){        mx=max(mx,b[i]);        mi=min(mi,a[i]);        dis[a[i]][b[i]]=i;        add(a[i],i);    }    fd(i,n,1){        fo(j,1,n)            fo(k,0,m)                f[j][k]=0;        fo(j,1,n){            x=dis[i][j];            if (x){                t=min(s[x],m-w[x]);                fd(k,t,0){                    if (k<=s[x]) g[j][k+w[x]]=max(g[j][k+w[x]],g[j][k]+v[x]);                }            }            fo(k,0,m){                g[j+1][k]=max(g[j+1][k],g[j][k]);            }            fo(k,0,m){                f[j][k]=max(f[j][k],g[j][k]);            }            t=h[j];            while (t){                y=go[t];                sum[0]=g[j][0];                fo(k,1,m) sum[k]=max(sum[k-1],g[j][k]);                num[0]=p[y][0];                fo(k,1,m) num[k]=max(num[k-1],p[y][k]);                fo(k,0,m){                    g[b[y]][k]=max(g[b[y]][k],g[j][k]+num[k]);                    g[b[y]][k]=max(g[b[y]][k],p[y][k]+sum[k]);                }                t=next[t];            }            if (x)                fo(k,0,m) p[x][k]=g[j][k];        }        fo(j,1,n)            fo(k,0,m)                g[j][k]=f[j][k],ans=max(ans,g[j][k]);    }    printf("%d\n",ans);}

AC的

#include <cstdio>#include <algorithm>#define fo(i,a,b) for(i=a;i<=b;i++)#define fd(i,a,b) for(i=a;i>=b;i--)using namespace std;const int maxn=500+10;struct dong{    int in,out,w,s,v;    void read(){        scanf("%d%d%d%d%d",&in,&out,&w,&s,&v);    }    friend bool operator <(dong a,dong b){        return a.out<b.out||a.out==b.out&&a.in>b.in;    }} p[maxn];int dp[maxn][maxn*2],f[maxn*2];int i,j,k,l,t,w,o,wi,n,m;int main (){    scanf("%d%d",&n,&m);    p[0]=(dong){0,2*maxn,0,m,0};    fo(i,1,n) p[i].read();    sort(p,p+n+1);    fo(i,0,n){        fo(j,p[i].w,m){            k=p[i].in;            t=min(p[i].s,j-p[i].w);            f[k]=0;            fo(l,0,i-1)                 if (p[l].in>=p[i].in){                    while (k<p[l].out){                        k++;                        f[k]=f[k-1];                    }                    f[k]=max(f[k],f[p[l].in]+dp[l][t]);                }            dp[i][j]=f[k]+p[i].v;        }    }    printf("%d\n",dp[n][m]);}
原创粉丝点击