luogu P3902 递增
时间复杂度O(nlogn)
规定low[k]是长度为 k 的子序列的末位数
low 数组单调递增
对于序列中一个数 a[i] 有两种可能
1. a[i] > low[ans]
就是 a[i] 可以接在现在最长子序列的后面,形成新的最长子序列,low[++ans]=a[i]
2. a[i] <= low[ans]
此时a[i] 不可以接在现在最长子序列的后面
当找到第一个大于等于 a[i] 的 low[k],那么a[i] 一定能接在low[k-1]后面形成新的、末位数更小的、长度为k的子序列,
比之前的 low[k] ,选择 a[i] 更小更有潜力,可以获得最优的值
所以 low[k] = a[i]
#include<cstdio> using namespace std; int low[100010]; int n,a[100010]; int fen(int l,int r,int x) { if(l==r) return l; while(l<r) { int mid=(l+r)/2; if(low[mid]<x) l=mid+1; else r=mid; } } int main() { scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&a[i]); int ans=1; low[ans]=a[0]; for(int i=1;i<n;i++) { if(a[i]>low[ans]) low[++ans]=a[i]; else low[fen(1,ans,a[i])]=a[i]; } printf("%d",n-ans); return 0; }