POI2015 MYJ
POI2015 MYJ
考虑从笛卡尔树的角度分析,我们设区间\([l,r]\)中最小值所在的位置为\(i\),则对于任意\([a_i,b_i]\sube [l,r],i\in [a_i,b_i]\),第\(i\)个区间的贡献只取决与店\(i\)的价格
所以设计状态\(dp_{l,r,k}\)表示区间\([l,r]\)中最小值为\(k\)时的最大收入,使用后缀和优化即可
时间复杂度\(O(n^3m)\)
#include<bits/stdc++.h>
using namespace std;
# define ll long long
# define read read1<ll>()
# define Type template<typename T>
Type T read1(){
T t=0;
char k;
bool vis=0;
do (k=getchar())=='-'&&(vis=1);while('0'>k||k>'9');
while('0'<=k&&k<='9')t=(t<<3)+(t<<1)+(k^'0'),k=getchar();
return vis?-t:t;
}
# define fre(k) freopen(k".in","r",stdin);freopen(k".out","w",stdout)
# define ll long long
int s,m,a[4005],b[4005],c[4005],d[4005],f[55][55][4005],g[55][55][4005],h[55][55][4005];
void pr(int l,int r,int p){
if(l>r)return;
p=h[l][r][p];
// cout<<l<<' '<<r<<' '<<p<<endl;
if(l==r){printf("%d ",d[p]);return;}
for(int i=l;i<=r;++i)
if(f[l][r][p]==f[l][i-1][p]+f[i+1][r][p]+d[p]*(-g[l][i-1][p]-g[i+1][r][p]+g[l][r][p])){
pr(l,i-1,p);
printf("%d ",d[p]);
pr(i+1,r,p);
return;
}
assert(0);
}void Max(int &x,int v){if(v>x)x=v;}
int main(){
s=read,m=read;
for(int i=1;i<=m;++i)
a[i]=read,b[i]=read,c[i]=d[i]=read;
sort(d+1,d+m+1);*d=unique(d+1,d+m+1)-d-1;
for(int i=1;i<=m;++i)c[i]=lower_bound(d+1,d+*d+1,c[i])-d;
for(int i=1;i<=m;++i)
++g[a[i]][b[i]][c[i]];
for(int i=s;i--;)
for(int j=i+1;j<=s;++j)
for(int k=*d;k;--k)
g[i][j][k]+=g[i][j-1][k]+g[i+1][j][k]-g[i+1][j-1][k];
for(int i=s;i;--i)
for(int j=i;j<=s;++j)
for(int k=*d;k;--k)
g[i][j][k]+=g[i][j][k+1];
for(int i=s;i;--i)
for(int j=i;j<=s;++j)
for(int l=*d;l;--l){
for(int k=i;k<=j;++k)
Max(f[i][j][l],f[i][k-1][l]+f[k+1][j][l]+d[l]*(-g[i][k-1][l]-g[k+1][j][l]+g[i][j][l]));
if(!h[i][j][l+1]||f[i][j][h[i][j][l+1]]<=f[i][j][l])h[i][j][l]=l;
else h[i][j][l]=h[i][j][l+1],f[i][j][l]=f[i][j][l+1];
}
printf("%d\n",f[1][s][1]);
pr(1,s,1);
return 0;
}
因果乃旋转纺车,光彩之多面明镜
浮世苍茫,不过瞬逝幻梦
善恶爱诳,皆有定数
于命运之轮中
吞噬于黄泉之冥暗
呜呼,吾乃梦之戍人
幻恋之观者
唯于万华镜中,永世长存
浮世苍茫,不过瞬逝幻梦
善恶爱诳,皆有定数
于命运之轮中
吞噬于黄泉之冥暗
呜呼,吾乃梦之戍人
幻恋之观者
唯于万华镜中,永世长存

浙公网安备 33010602011771号