在给定序列中寻找一个1~n+1递增,n~2n+1递减的序列,我的想法是直接对原序列和原序列的反序列用nlgn算法求递增序列,例如序列a[]={1,2,4,1,2,6},它的反序列为b[]={6,2,1,4,2,1},序列a的上升数组为aa[]={1,2,3,1,2,4},序列b的上升数组为bb[]={1,1,1,2,2,1},然后枚举从下标0~5,得到最长满足条件的序列:
for(int i=0;i<n;++i){
int cnt=min(aa[i],bb[n-1-i]); //aa[i]就是当前最长上升长度,bb[n-1-i]就是当前最长下降长度,由于两者可能长度不等就取较小值。
ans=max(cnt*2-1,ans);
}
AC代码:
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=10000+5;
int n;
int a[maxn],b[maxn];
int inc[maxn],dec[maxn];
void deal(int *p,int *ans){
int len[maxn];
int c=1;
ans[0]=1;
len[0]=p[0];
for(int i=1;i<n;++i){
int k=lower_bound(len,len+c,p[i])-len;
if(k>=c) len[c++]=p[i];
else {
if(p[i]<len[k]) len[k]=p[i];
}
ans[i]=k+1;
}
}
int main(){
while(scanf("%d",&n)!=EOF){
for(int i=0;i<n;++i) {
scanf("%d",&a[i]);
b[n-1-i]=a[i];
}
deal(a,inc);
deal(b,dec);
int ans=-1;
for(int i=0;i<n;++i){
int cnt=min(inc[i],dec[n-1-i]);
ans=max(cnt*2-1,ans);
}
printf("%d\n",ans);
}
return 0;
}
如有不当之处欢迎指出!