最长上升子序列nlogn做法

需要存储:相同长度的上升子序列,结尾元素最小的值是多少。相同长度下,结尾元素越小,下一个可接上的阈值就越大。而随着上升子序列长度的增加,结尾元素的最小值是单调递增的。比如当前数为ai,我们要把ai接到当前数组dp中最大的数之后,因为数最大也就意味着长度最长。于是,对于每个ai,我们在dp数组中找小于它的最大值,而更新大于等于它的最小值(即lower_bound对应的元素)。dp数组的元素都初始化为INF。

 

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 7;
const int INF = 0x3f3f3f3f;
int a[maxn], dp[maxn];  //dp存储所有不同长度的上升子序列结尾的最小值
int main()
{
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);
    fill(dp + 1, dp + 1 + n, INF);
    for(int i = 1; i <= n; ++i)
         *lower_bound(dp + 1, dp + 1 + n, a[i]) = a[i];
    printf("%d\n", lower_bound(dp + 1, dp + 1 + n, INF) - dp - 1);
}

 

posted @ 2020-12-16 09:02  .Ivorelectra  阅读(107)  评论(0编辑  收藏  举报