导弹拦截
LIS 用二分可以O(nlogn)
Dilworth定理,大概就是一个序列的不下降子序列的最小数量等于这个序列的最长上升子序列的长度
感性理解
赵宗昌老师讲了向前和向后求最长上升子序列的方法,又理解了动归
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn=1e5+7; int a[maxn],n,f[maxn],l,r,mid; int main(){ while(cin>>a[++n]);n--; int ans1=0; f[0]=2147483647; for(int i=1;i<=n;i++){ if(f[ans1]>=a[i]){ f[ans1+1]=a[i]; ans1++; } else{ int l=0;r=ans1; while(l<r){ mid=(l+r)/2; if(f[mid]>=a[i]) l=mid+1; else r=mid; }if(l!=0) f[l]=a[i]; } } cout<<ans1<<endl; memset(f,-1,sizeof(f)); int ans2=0; for(int i=1;i<=n;i++){ if(f[ans2]<a[i]){ f[ans2+1]=a[i]; ans2++; } else{ l=0;r=ans2; while(l<r){ mid=(l+r)/2; if(f[mid]>=a[i]) r=mid; else l=mid+1; } f[l]=a[i]; } } cout<<ans2<<endl; return 0; }
不可以相等用upper_bound 可以用lower_bound
upper_bound是大于的第一个数,lower_bound是大于等于的第一个数