[CF480D]Parcels

题目描述

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]);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值