最长上升子序列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); }