。。。

导航

hdu 1950 【最长上升子序列 复杂度nlogn】

http://acm.split.hdu.edu.cn/showproblem.php?pid=1950

思路:输入t,再输入t组数,每组数输入一个n,再输入n个数,求最长上升子序列长度(非连续)。

这个题用的是复杂度nlogn的方法实现,写了杭电另一道题同类型题,用O(n*n)的方法会超时,结果发现了这个新的方法 有趣~

#include<stdio.h>
#define N 40010

int end[N],num[N];
//end数组存储的是子序列长度为i的最小尾数 
int find(int flag,int *end,int low,int high)
{//二分法查找end中最小的小于数flag的下标 
    int mid;
    while(low < high)
    {
        mid = (low+high)>>1;
        if(flag > end[mid])
            low = mid + 1;
        else
            high = mid;
    }
    return low;
}

int main()
{
    int t,n,i,len,ans;
    scanf("%d",&t);
    while(t --)
    {
        scanf("%d",&n);
        for(i = 1; i <= n; i ++)
            scanf("%d",&num[i]);
        end[1] = num[1],len = 1;//len记录子序列最长长度 
        for(i = 2; i <= n; i ++)
        {
            if(num[i] > end[len])
                ans = ++len;
            else
                ans = find(num[i],end,1,len+1);
            end[ans] = num[i];
        }
        printf("%d\n",len);
    }
    return 0;
}

 

posted on 2017-10-10 16:54  大学僧  阅读(125)  评论(0编辑  收藏  举报