線段樹解LIS
阿新 • • 發佈:2018-11-01
先是nlogn的LIS解法
/* LIS nlogn解法 */ #include<iostream> #include<cstring> #include<cstdio> using namespace std; //結尾的數字越小,說明相同長度下當前序列越優 int lis[100005],a[100005];//lis[i]表示長度為i的最優的結尾數 int n,len=0; int find(int x){//找到lis中第一個大於等於x的數的下標 int l=0,r=len; while(l<r){ int mid=l+r>>1; if(lis[mid]>=x) r=mid; else l=mid+1; } return l; } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); lis[1]=a[1];len++; for(int i=2;i<=n;i++){//按順序處理每一個數 if(a[i]>lis[len])//可以更新新長度了 lis[++len]=a[i];else{//對於一個a[i],可以更新以它為結尾的最長lis的結尾 int pos=find(a[i]);//找到lis中第一個大於等於a[i]的數,pos也是以那個數結尾的長度 lis[pos]=a[i]; //把那個數替換了 } } printf("%d\n",len); return 0; }
線段樹解LIS