感觉上这个题是可以直接暴力的,每次根据一段连续最小值个数的奇偶性决定是否划分区间,递归处理。然而写起来实在太麻烦了。
设f[i][j]为以i为左端点合并出j时的右端点。则有f[i][j]=f[f[i][j-1]+1][j-1]。类似于区间dp。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; int read() { int x=0,f=1;char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } #define N 300000 int n,a[N],f[N][60],ans; int main() { #ifndef ONLINE_JUDGE freopen("a.in","r",stdin); freopen("a.out","w",stdout); const char LL[]="%I64d "; #else const char LL[]="%lld "; #endif n=read(); for (int i=1;i<=n;i++) a[i]=read(); memset(f,255,sizeof(f)); for (int i=1;i<=n;i++) f[i][a[i]]=i; for (int j=1;j<60;j++) for (int i=1;i<=n;i++) if (~(f[i][j]=f[f[i][j-1]+1][j-1]==-1?f[i][j]:f[f[i][j-1]+1][j-1])) ans=j; cout<<ans; return 0; }