Poj 1631 n*logn 的最长上升子序列(LIS)算法

这里找到题目

题意是找出让连线不交错的最大剩余线的个数

一看题就知道是求最长上升子序列
但是,看看数据范围就知道,很明显普通的LIS算法会超时
这个时候,我们就要优化。

多创建一个d数组和int len 变量,d[len] 表示长度为len的上升子序列的最后一个元素,如果读入一个数,它的值为x,有d[i] < x < d[i+1]的话,我们就把d[i+1] 赋值为 x,当然,如果i+1>len的话,len++。
利用d数组的单调性我们可以轻松用log n的复杂度找到 上面的那个i
最后算出的len就是答案。

下面贴代码

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
using namespace std;
const int maxn = 40010;
//int a[maxn];一开始我还想保存所有读入的数,事实证明我想多了,没必要
int d[maxn];

int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        int p,x;
        scanf("%d",&p);
        scanf("%d",&x);
        int len = 1;
        d[len] = x;
        for(int i=1;i<p;i++){
            scanf("%d",&x);
            int t = lower_bound(d+1,d+len+1,x) - (d+1);
            //printf("%d t\n",t);
            if(t==len){
                len++;
                d[len] = x;
            }else {
                d[t+1] = x;
            }
        }
        printf("%d\n",len);

    }
    return 0 ;


}

如果觉得我讲的不好,请参考最长上升子序列(LIS)n*log n 算法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章