[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;
}