LIS 最長上升子序列 (n*logn) 模板 (二分查詢+遞迴)
阿新 • • 發佈:2019-01-01
最長上升子序列是很早就接觸了的問題了,一直用的是動態規劃n*n的方法,也知道那不是最好的,可以優化,今天看部落格無意中看到LIS,LCS兩個詞,就特意找了部落格看了看,主要是理解一下這裡的思想,其實蠻複雜難懂的,自己很難說清楚,還是得引用人家的部落格才行。點選開啟連結
下面還有模板:
#include<iostream> #include<cstring> using namespace std; int a[1000]; int dp[1000]; int BinarySearch(int x, int len)//二分查詢dp[]裡面第一個大於等於x的數 { int left=1, right=len, mid; while(left<=right) { mid=(left+right)/2; if(x==dp[mid]) return mid; else if(x>dp[mid]) left=mid+1; else if(x<dp[mid]) right=mid-1; } return left; } int main() { int N; while(cin>>N) { memset(dp, 0, sizeof(dp)); for(int i=1; i<=N; i++) { cin>>a[i]; } dp[1]=a[1]; int len=1;//當前已經求出來的最長序列長度 int j;//dp[]的下標 for(int i=2; i<=N; i++) { //if(a[i]<dp[1]) // j=1; if(a[i]>dp[len])//如果a[i]>dp[len] len +1 j=++len; else//反之, 更新j j=BinarySearch(a[i], len); dp[j]=a[i];//把a[i]更新入dp[]陣列 } cout<<len<<endl; } return 0; }