1 1065 1284 导弹拦截
最长上升子序列
POJ2533
题意显然。
子序列:序列({a_n}),则其一个子序列是存在一些数(j_x),使得(1le j_1<j_2<...le n),构成子序列({a_j})
题解
( ext{O}(n^2))
设(f_i)表示以(a_i)结尾的上升子序列最长为多少。初始化显然每个(f都为1)。我们从(1)~(i-1)枚举(f_j),当(a_j<a_i)时,(f_i=max(f_i,f_j+1))
最后我们输出最大的(f_i)即可。
(O(nlog n))
设原数组为(a_n),设(f_i)表示长度为(i)的序列中最长上升的最小值(他是原数组的数值)
如果a[i]>dp[len],len表示当前LIS最长长度,就直接放入末尾
否则,在dp数组中寻找第一个大于等于a[i]的位置,把他替换成a[i],这样的话dp[len]的数值变得稍小,可以更好地在后面接上升序列
for(int i=1; i<=n; i++){
if(a[i]>dp[len]) dp[++len]=a[i];
else{
dp[lower_bound(dp+1,dp+1+len,a[i])-dp]=a[i];
}
}