[BZOJ4380] [POI2015] Myjnie

[BZOJ4380] [POI2015] Myjnie

题目链接

https://www.lydsy.com/JudgeOnline/problem.php?id=4380

Solution

考虑\(\rm dp\),设\(f_{l,r,x}\)表示\([l,r]\)区间填的数最小值为\(x\)

转移我们枚举\([l,r]\)的一个位置,把\(x\)填进去,两侧只要满足最小值\(\geqslant x\)就行了。

那么我们可以前缀\(\rm max\)优化之后暴力转移。

复杂度\(O(n^3m)\)

Code

#include<bits/stdc++.h>
using namespace std;

void read(int &x) {
    x=0;int f=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
    for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
}
 
void print(int x) {
    if(x<0) putchar('-'),x=-x;
    if(!x) return ;print(x/10),putchar(x%10+48);
}
void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');}

#define lf double
#define ll long long 

#define pii pair<int,int >
#define vec vector<int >

#define pb push_back
#define mp make_pair
#define fr first
#define sc second

#define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++) 

const int N = 52;
const int M = 5050;
const int inf = 1e9;
const lf eps = 1e-8;
const int mod = 1e9+7;

int f[N][N][M],g[N][N][M],p[N][N][M],n,m,a[M],b[M],c[M],t[M],L,s[M],d[N];

void init() {
    read(n),read(m);for(int i=1;i<=m;i++) read(a[i]),read(b[i]),read(c[i]),t[i]=c[i];
    sort(t+1,t+m+1);L=unique(t+1,t+m+1)-t-1;
    for(int i=1;i<=m;i++) c[i]=lower_bound(t+1,t+L+1,c[i])-t;
}

void dfs(int l,int r,int x) {
    if(l>r) return ;
    if(l==r) return d[l]=t[x],void();int F=p[l][r][x];d[F]=t[x];
    for(int i=x;i<=L;i++) if(g[l][F-1][x]==f[l][F-1][i]) {dfs(l,F-1,i);break;}
    for(int i=x;i<=L;i++) if(g[F+1][r][x]==f[F+1][r][i]) {dfs(F+1,r,i);break;}
}

int main() {
    init();
    for(int len=1;len<=n;len++)
        for(int l=1;l+len-1<=n;l++) {
            int r=l+len-1;
            for(int x=1;x<=L;x++) p[l][r][x]=l;
            for(int i=l;i<=r;i++) {
                for(int x=1;x<=L;x++) s[x]=0;
                for(int x=1;x<=m;x++) if(a[x]>=l&&b[x]<=r&&a[x]<=i&&b[x]>=i) s[c[x]]++;
                for(int x=L;x;x--) s[x]=s[x+1]+s[x];
                for(int x=L;x;x--) {
                    int res=s[x]*t[x]+g[l][i-1][x]+g[i+1][r][x];
                    if(f[l][r][x]<res) f[l][r][x]=res,p[l][r][x]=i;
                }
            }
            for(int x=L;x;x--) g[l][r][x]=max(f[l][r][x],g[l][r][x+1]);
        }
    int ans=0,pos=0;
    for(int i=1;i<=L;i++) if(f[1][n][i]>ans) ans=f[1][n][i],pos=i;
    write(ans);dfs(1,n,pos);
    for(int i=1;i<=n;i++) printf("%d ",d[i]);puts("");
    return 0;
}
posted @ 2019-06-24 20:57  Hyscere  阅读(167)  评论(0编辑  收藏  举报