UVA 10534最长上升子序列运用

来源:互联网 发布:淘宝店铺被屏蔽怎么办 编辑:程序博客网 时间:2024/06/13 10:10

   在给定序列中寻找一个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;}

如有不当之处欢迎指出!

0 0