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 算法

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