• P3592 [POI2015]MYJ


    P3592 [POI2015]MYJ


    一道比较烦的区间dp。。

    昨天上课讲到了这题,然后就在lg翻到了

    然后调了很久很久。。。。。

    (f[l][r][k])为区间([l,r])中,最小值(geq k)的最大收益(只算被([l,r])包含的)

    然后枚举最小值的位置(p),那么包含(p)的区间答案全部是(k)了,只需要算两边的

    然后发现很多东西不好算。。。比如说包含(p)的区间,所以设(h[i][j])为当前区间穿过(i),且(c>=j)的区间数量,到每个区间都重新求一下,就好做了

    (f[l][r][k]=max(max(f[l][p-1][k]+f[p+1][r][k]+h[p][k] imes k,pin[l,r]),f[l][r][k+1]))

    然后输出方案比较麻烦略略略

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cctype>
    using namespace std;
    typedef int mmp;
    #define vd void
    #define rg register
    #define il inline
    #define sta static
    #define mp make_pair
    il int gi(){
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    int a[4001],b[4001],c[4001],C[4001];
    pair<long long,int>f[54][54][4002];
    int h[51][4002];
    int S[51];
    il vd dfs(int l,int r,int k){
        if(l>r)return;
        while(f[l][r][k].first==f[l][r][k+1].first&&k<C[0])++k;
        int p=f[l][r][k].second;
        if(p==0)return;
        S[p]=C[k];
        dfs(l,p-1,k),dfs(p+1,r,k);
    }
    mmp main(){
        freopen("4380.in","r",stdin);
        freopen("4380.out","w",stdout);
        int n=gi(),m=gi();
        for(rg int i=1;i<=m;++i)a[i]=gi(),b[i]=gi(),c[i]=C[i]=gi();
        sort(C+1,C+m+1);
        C[0]=unique(C+1,C+m+1)-C-1;
        for(rg int i=1;i<=m;++i)c[i]=lower_bound(C+1,C+C[0]+1,c[i])-C;
        for(rg int i=1;i<=m;++i){
            if(a[i]!=b[i])continue;
            for(rg int j=1;j<=c[i];++j)
                f[a[i]][a[i]][j].first+=C[j];
        }
    	for(rg int i=1;i<=n;++i)
    		for(rg int j=C[0];j;--j)
    			f[i][i][j].second=i;
    	for(rg int i=1;i<=n;++i)
    		for(rg int j=C[0]-1;j;--j)
    			f[i][i][j]=max(f[i][i][j],f[i][i][j+1]);
        for(rg int sz=2;sz<=n;++sz)
            for(rg int l=1;l+sz-1<=n;++l){
                int r=l+sz-1;
                for(rg int i=1;i<=n;++i)
                    for(rg int j=1;j<=C[0];++j)
                        h[i][j]=0;
                for(rg int i=1;i<=m;++i)
                    if(l<=a[i]&&b[i]<=r)
                        ++h[a[i]][1],--h[a[i]][c[i]+1],--h[b[i]+1][1],++h[b[i]+1][c[i]+1];
                for(rg int i=l;i<=r;++i)
                    for(rg int j=1;j<=C[0];++j)
                        h[i][j]+=h[i-1][j]+h[i][j-1]-h[i-1][j-1];
                for(rg int i=C[0];i;--i){
                    for(rg int j=l;j<=r;++j)
                        if(f[l][j-1][i].first+f[j+1][r][i].first+h[j][i]*C[i]>=f[l][r][i].first)
                            f[l][r][i]=mp(f[l][j-1][i].first+f[j+1][r][i].first+h[j][i]*C[i],j);
                    f[l][r][i]=max(f[l][r][i+1],f[l][r][i]);
                }
            }
        int ans=1;
        for(rg int i=2;i<=C[0];++i)
            if(f[1][n][i].first>=f[1][n][1].first)ans=i;
        printf("%lld
    ",f[1][n][ans].first);
        dfs(1,n,ans);
        for(rg int i=1;i<=n;++i){
    		if(S[i]==0)S[i]=C[C[0]];
    		//printf("%d ",S[i]);
    	}
        return 0;
    }
    
  • 相关阅读:
    kernel-devel-3.10.0-957.el7.x86_64.rpm kernel-headers-3.10.0-957.el7.x86_64.rpm
    解决MySQL安装:找不到msvcr120.dll和msvcp120.dll
    Node.js安装
    大数据电商数据仓库
    spark
    redis 脑裂等极端情况分析
    Redis解决并发超卖问题
    解决OutOfMemoryError: unable to create new native thread问题
    好用的java工具
    java初始化和实例化
  • 原文地址:https://www.cnblogs.com/xzz_233/p/8662387.html
Copyright © 2020-2023  润新知