在给定序列中寻找一个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; }
如有不当之处欢迎指出!