hdu1950 Bridging signals

LIS

nlogn的时间复杂度,之前没有写过。

思路是d[i]保存长度为i的单调不下降子序列末尾的最小值。

更新时候,如果a[i]>d[len],(len为目前最长的单调不下降子序列) d[++len]=a[i]

否则 二分查找 d[j-1]<a[i]<d[j] 并更新 d[j]=a[i]

 

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#define LL long long
using namespace std;
LL read()
{
    LL x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10ll+ch-'0';ch=getchar();}
    return x*f;
}

const int maxn = 40000 + 10;

int n,len;
int a[maxn];
int d[maxn];
int l,r,mid;

void build() 
{
    n=read();
    for(int i=1;i<=n;i++) a[i]=read();    
    memset(d,0,sizeof(d));
    
    d[1]=a[1];
    len=1;
    for(int i=2;i<=n;i++) 
    {
        if(a[i]>d[len]) 
            d[++len]=a[i];    
        else
        {
            l=1; r=len;
            while(l<r) 
            {
                mid=(l+r)/2;
                if(d[mid]>a[i]) 
                    r=mid;
                else 
                    l=mid+1;
            }
            d[l]=a[i];
        }
    }
    //printf("Tets\n");
    //for(int i=1;i<=n;i++) printf("%d ",d[i]);
    printf("%d\n",len);
}


void solve() 
{
    
}

int main() 
{
    int T;
    scanf("%d",&T);
    while(T--) 
    {
        build();
        solve();
    }
    
    return 0;
}
posted @ 2018-03-25 21:02  invoid  阅读(132)  评论(0编辑  收藏  举报