//O(Nlogn)算法
//同样a,dp两个数组,a中存放序列的每个值
//dp[i]指长度为i的序列中最后一个值的最小值,例如有两个相同长度的序列1,3,6和1,3,4则dp[3] = 4;
//有两种算法
//dp中全为最大值INT_MAX时
for (int i = 1; i <= n; ++i)
{
int pos = lower_bound(dp + 1, dp + 1 + n,a[i]) - dp;//返回在dp中第一个大于等于a[i]的下标,pos的最大值就是最长递增子序列的长度
dp[pos] = a[i];
}
//二:dp中全为-1
for (int i = 1; i <= n; ++i)
{
int pos = upper_bound(dp + 1, dp + 1 + n, a[i]) - dp;//返回在dp中第一个小于a[i]的下表,这种并非严格递增,是大于等于递增
dp[pos] = a[i];
}
状态空间:b[i]表示从a[0]到a[i]且终止于 a[i]的最长递增序列的长度。
状态转移方程:b[i]=b[k]+1(k<i, a[k]为从i向左小于a[i]且b[k]最大的元素
初始条件: b[0]=1
结果:b[i]中的最大值
复杂度:n2
优化:引入数组c[i]表示数列0项到i项中的长度为i的递增子序列的末尾元素值的最小值。显然数组c必然是单调递增的。复杂度:nlog2n
状态转移方程:
c[0]=-1
c[j]=a[i] // j为a[i]在c中的第一个比它大元素的位(upper_bound())
b[i]=j