• bzoj4380: [POI2015]Myjnie


    区间DP 去%栋老师

    我写得不够优越,h数组复杂了

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int maxn=51;
    const int maxm=4001;
    
    struct node{int l,r,c;}p[maxm];
    int lslen,ls[maxm];
    
    int f[maxn][maxn][maxm],g[maxn][maxn][maxm];//当前区间的最小值为c的最大收益 g是f的后缀最大值 
    int h[maxn][maxn][maxm];//有多少ci大于等于c的人 
    //simple
    
    int u[maxn][maxn][maxm],q[maxn][maxn][maxm];//f这个状态转移的断点 g这个最大来自于那个f
    //reback
    
    int as[maxn];
    void dfs(int l,int r,int c)
    {
        if(l>r)return ;
        int p=q[l][r][c];
        int k=u[l][r][p];
        as[k]=p;
        dfs(l,k-1,p);
        dfs(k+1,r,p);
    }
    
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&p[i].l,&p[i].r,&p[i].c);
            ls[++lslen]=p[i].c;
        }
        sort(ls+1,ls+lslen+1);
        lslen=unique(ls+1,ls+lslen+1)-ls-1;
        for(int i=1;i<=m;i++)
            p[i].c=lower_bound(ls+1,ls+lslen+1,p[i].c)-ls;
        
        for(int l=1;l<=n;l++)
            for(int r=l;r<=n;r++)
            {
                for(int i=1;i<=m;i++)
                    if(l<=p[i].l&&p[i].r<=r)h[l][r][p[i].c]++;
                for(int c=lslen;c>=1;c--)
                    h[l][r][c]+=h[l][r][c+1];
            }
            
        for(int i=1;i<=n;i++)
            for(int c=lslen;c>=1;c--)
            {
                f[i][i][c]=ls[c]*h[i][i][c];
                u[i][i][c]=i;
                if(g[i][i][c+1]>f[i][i][c])g[i][i][c]=g[i][i][c+1],q[i][i][c]=q[i][i][c+1];
                else g[i][i][c]=f[i][i][c],q[i][i][c]=c;
            }
        for(int L=2;L<=n;L++)
            for(int l=1;l+L-1<=n;l++)
            {
                int r=l+L-1;
                for(int c=lslen;c>=1;c--)
                    for(int k=l;k<=r;k++)
                    {
                        int d=g[l][k-1][c]+g[k+1][r][c]+(h[l][r][c]-h[l][k-1][c]-h[k+1][r][c])*ls[c];
                        if(f[l][r][c]<=d)
                        {
                            f[l][r][c]=d;
                            u[l][r][c]=k;
                            if(g[l][r][c+1]>f[l][r][c])g[l][r][c]=g[l][r][c+1],q[l][r][c]=q[l][r][c+1];
                            else g[l][r][c]=f[l][r][c],q[l][r][c]=c;
                        }
                    }
            }
        printf("%d
    ",g[1][n][1]);
        dfs(1,n,1);
        for(int i=1;i<n;i++)printf("%d ",ls[as[i]]);
        printf("%d
    ",ls[as[n]]);
            
        return 0;
    }
  • 相关阅读:
    HTML <iframe> 标签
    HTML <tr> 标签
    HTML <img> 标签的 border 属性
    jQuery ajax ajax() 方法
    CSS padding 属性
    SQL Server CONVERT() 函数
    CSS overflow 属性
    HTML <input> 标签
    Java动态代理一——动态类Proxy的使用
    Java拆箱装箱小结
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/10284101.html
Copyright © 2020-2023  润新知