LIS 的 n*logn 写法并标记输出其中任意一个

来源:互联网 发布:淘宝客助手 编辑:程序博客网 时间:2024/05/04 08:36
<pre name="code" class="cpp">#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn = 3010;int q[maxn],path[maxn],c[maxn],st[maxn],n;//q:最长上升子序列的下标,path:该位置在上升子序列中前一个位置的下表 c:原序列,st:最后保存一个最长上升子序列int bin_search(int x,int l,int r)//返回已知的最长上升子序列中最后一个小于x的位置+1{    while(l<=r)    {        int mid=(l+r)>>1;        if(c[q[mid]]<x)            l=mid+1;        else            r=mid-1;    }    return l;}int main(){    //freopen("lis.in","r",stdin);    //freopen("lis.out","w",stdout);    while(~scanf("%d",&n))    {        for(int i=0; i<n; i++)            scanf("%d",&c[i]);        int len=0;        q[len++]=0;        path[0]=0;        for(int i=0; i<n; i++)        {            if(c[i]>c[q[len-1]])//已求的序列中没有比这个数大的,最长上升子序列加1            {                path[i]=q[len-1];                q[len++]=i;            }            else            {                int idex = bin_search(c[i],0,len-1);//寻找已知子序列中最后一个比它小的位置,该数放在其后                path[i] = idex ? q[idex-1] : 0;                q[idex] = i;            }        }        int k=0;        printf("%d\n",len);        st[k++]=c[q[len-1]];        int tmp=q[len-1];        while(--len)        {            tmp = path[tmp];            st[k++]=c[tmp];        }        for(int i=k-1;i>=0;i--)            printf(i==0?"%d\n":"%d ",st[i]);    }    return 0;}/**72 3 1 4 0 3 6*/



                                             
0 0
原创粉丝点击