问题描述:给出一个数列,找出这个数列中最长上升子序列中所包含的个数。最长上升子序列指对于数列an对于任意i小于j,满足ai小于aj的子序列
很容易能想到一个dp的方法:
dp[i]=以i为末尾的最长上升子序列
但是该方法复杂度为O(n^2),我们发现上升子序列末尾的数字越小,它后面就越有优势,所以我们可以转而求在相同长度下,末尾元素的最小值。该算法的复杂度也为O(n^2),但因为dp数组是单调递增的,我们可以用二分的方法来进一步优化,这样时间复杂度就是O(n*log n)
const int oo = 0x3f3f3f3f;
int dp[maxn];
int n;
int a[maxn];
void solve() {
fill(dp, dp + n, oo);
for (int i = 0; i < n; i++) {
*lower_bound(dp, dp + n, a[i]) = a[i];
}
cout << lower_bound(dp, dp + n, oo) - dp << endl;
}