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\n",g[1][n][1]);
    dfs(1,n,1);
    for(int i=1;i<n;i++)printf("%d ",ls[as[i]]);
    printf("%d\n",ls[as[n]]);
        
    return 0;
}

 

posted @ 2019-01-17 19:15  AKCqhzdy  阅读(161)  评论(0编辑  收藏  举报