Problem:
OwO http://acm.hdu.edu.cn/showproblem.php?pid=6049
(multi-university Training contest-team 2-1005)
Solution:
Preprocessing first
MN[I][J] Record interval minimum, mx[i][j] record interval maximum, if the mn-mx+1 and interval number of the same number, the interval can be classified into a small segment
F[I][J] Record (I,J) segment can be divided into a few small segments, Sav[i] records the right end of the last feasible interval starting from I
And then we can solve it.
Set the interval to be exchanged for Seg_a,seg_b.
First of all, the left and right endpoints of seg_a, I and J, Seg_a must be satisfied, that is, f[i][j]!=0, and must be satisfied, seg_a to the leftmost segment or seg_a to the left of the segment includes (1,i-1) number
For each viable seg_a, set K to the maximum value in Seg_a, the
1. If k==n, then Seg_b is the rightmost segment.
2. Otherwise seg_b to the right of SEG (K+1,N) and must include (k+1,n) all the numbers in the
Then enumerating Seg_b's left endpoint T makes the seg_b legal and must satisfy the mn[t][k]==i to ensure that the entire sequence is incremented from Seg_b after Seg_a and 1~n exchange
(Ideas come from the interpretation of the standard process)
(There seems to be a better solution)
1#include <iostream>2#include <cstring>3#include <cstdio>4#include <algorithm>5#include <cmath>6 7 using namespacestd;8 9 Const intm=3044;Ten One intN; A intS[m]; - intF[m][m],mn[m][m],mx[m][m]; - intSav[m],ans; the - voidInit () - { -Memset (F,0,sizeof(f)); + inti,j,k; - for(i=1; i<=n;i++) + { Asav[i]=i; atf[i][i]=1; -mn[i][i]=mx[i][i]=S[i]; - } - for(i=1; i<=n;i++) - for(j=i+1; j<=n;j++) - { inMx[i][j]=max (mx[i][j-1],s[j]); -Mn[i][j]=min (mn[i][j-1],s[j]); to } + for(i=2; i<=n;i++) - for(j=1; j+i-1<=n;j++) the { *k=j+i-1; $ if(mx[j][k]-mn[j][k]+1!=k-j+1)Panax Notoginsengf[j][k]=0; - Else the { + if(mn[j][k]<Mn[j][sav[j]]) Af[j][k]=1; the Else +f[j][k]=f[j][sav[j]]+f[sav[j]+1][k]; -sav[j]=K; $ } $ } - } - the voidSolve () - {WuyiAns=max (1, f[1][n]); the inti,j,k,t,tmp; - //Swap (I,J), (t,k) Wu for(i=1; i<=n;i++) - for(j=i;j<=n;j++) About if(F[i][j] && (i==1|| (f[1][i-1] && mn[1][j-1]==1)))//Be sure the first seg are start from 1 or the SEG (i,j) $ { -k=Mx[i][j]; - if(K==n | | (f[k+1][n] && mx[k+1][n]==N)) - for(t=j+1; t<=k;t++) A if(Mn[t][k]==i &&F[t][k]) +Ans=max (ans,f[1][i-1]+1/*Seg[i][j]]*/+f[j+1][t-1]+1/*Seg[t][k]*/+f[k+1][n]); the } - } $ the intMain () the { the intt,i,j; theCin>>T; - while(t--) in { thescanf"%d",&n); the for(i=1; i<=n;i++) Aboutscanf"%d",&s[i]); the init (); the solve (); thecout<<ans<<Endl; + } - return 0; the}Donnot Click Me
Hdu 6049-SDJPX is Happy