最长上升子序列(LIS)
算法思路:
固定当前位,看前面能有几位数能和当前位去组成上升子序列,在从里面找出最长的
模板:
for(int i=0;i<n;i++){f[i]=1;for(int j=0;j<i;j++){if(a[j]<a[i])f[i]=max(f[i],f[j]+1);}}
贪心+二分优化:
我们尽可能的让序列长度最大,那么当前位越小,后面能够组成的长度的潜力就越大,而这个数组就是每个长度级别的最小末尾值,数组长度就是最长上升子序列的长度,数组一定是递增的,我们就可以通过二分去优化查找符合条件的数。
二分查找过程:
放入a[i]
二分查找f数组,a[i]能放到哪里,如果a[i]比数组中的每个数都大,则放入数组最后一位,如果都小,则替换数组中的第一个比a[i]大的位置
注意:f数组中第一位永远是非常小的数,代码中可以不做初始化
模板:
int len=0;for(int i=0;i<n;i++){int l=0,r=len;while(l<r){int mid=(l+r+1)>>1;if(f[mid]<a[i])l=mid;else r=mid-1;}len=max(len,r+1);f[r+1]=a[i];}cout<<len<<endl;
