51NOD 最长递增子序列(模板)
给出长度为N的数组,找出这个数组的最长递增子序列。(递增子序列是指,子序列的元素是递增的)
例如:5 1 6 8 2 4 5 10,最长递增子序列是1 2 4 5 10。
Input
第1行:1个数N,N为序列的长度(2 <= N <= 50000) 第2 - N + 1行:每行1个数,对应序列的元素(-10^9 <= S[i] <= 10^9)
Output
输出最长递增子序列的长度。
Input示例
8 5 1 6 8 2 4 5 10
Output示例
5
O(n^2) TLE
1 #include <iostream> TLE 2 #include <cstring> 3 #define N 50010 4 using namespace std; 5 int num[N],dp[N]; 6 int main(){ 7 cin.sync_with_stdio(false); 8 int n; 9 while(cin>>n){ 10 for(int i=0;i<n;i++){ 11 cin>>num[i]; 12 dp[i]=1; 13 } 14 for(int i=1;i<n;i++){ 15 for(int j=0;j<i;j++){ 16 if(num[i]>num[j]){ 17 dp[i]=max(dp[i],dp[j]+1); 18 } 19 } 20 } 21 int mmax=dp[0]; 22 for(int i=1;i<n;i++){ 23 mmax=max(mmax,dp[i]); 24 } 25 cout<<mmax<<endl; 26 } 27 return 0; 28 }
O(N*logN)
1 #include <iostream> 2 #include <cstring> 3 #define N 50010 4 using namespace std; 5 int num[N],dp[N]; 6 int BiSearch(int len,int key){//二分法 7 int l=0,r=len-1; 8 while(l<=r){ 9 int mid=(l+r)/2; 10 if(dp[mid]>key){ 11 r=mid-1; 12 } 13 else if(dp[mid]<key){ 14 l=mid+1; 15 } 16 else{ 17 return mid; 18 } 19 } 20 return l; 21 } 22 int main(){ 23 cin.sync_with_stdio(false); 24 int n; 25 while(cin>>n){ 26 for(int i=0;i<n;i++){ 27 cin>>num[i]; 28 } 29 int len=1; 30 dp[0]=num[0]; 31 for(int i=1;i<n;i++){ 32 if(num[i]>dp[len-1]){ 33 dp[len]=num[i]; 34 len++; 35 } 36 else{ 37 int pos=BiSearch(len,num[i]); 38 dp[pos]=num[i]; 39 } 40 } 41 cout<<len<<endl; 42 } 43 return 0; 44 }
2016-12-10 16:43:12