最長遞增長度 (最長上升子序列)


最長遞增長度

題目描述

給定一個長度為n的整數序列S,求這個序列中最長的嚴格遞增子序列的長度。

輸入描述:

第一行,一個整數n (2<=n<=50000),表示序列的長度

第二行,有n個整數 (-10^9 <= S[i] <= 10^9),表示這個序列

輸出描述:

輸出一個整數,表示最長遞增子序列的長度

輸入

6
4 0 5 8 7 8

輸出

4

備注:

樣例解釋 子序列為 0 5 7 8


思路:這題是最長上升子序列模板題,有兩種寫法,但是 o(n^2)被卡了,會超時,應該用二分搜索,時間復雜度 o(nlogn)......


o(n^2)寫法:


 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<map>
 7 #include<set>
 8 #include<vector>
 9 using namespace std; 10 #define ll long long
11 const int maxn=5e4+5; 12 int dp[maxn]; 13 int num[maxn]; 14 int main() 15 { 16     ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); 17     memset(dp,0,sizeof(dp)); 18     int n; 19     cin>>n; 20     for(int i=1;i<=n;i++) 21         cin>>num[i]; 22     int ans=-1; 23     for(int i=1;i<=n;i++) 24  { 25         dp[i]=max(dp[i],1);//最短起碼為1
26         for(int j=i+1;j<=n;j++) 27  { 28             if(num[j]>=num[i])//連續
29                 dp[j]=max(dp[j],dp[i]+1);//刷新dp[j]
30  } 31         ans=max(ans,dp[i]);//找最長上升子序列長度
32  } 33     cout<<ans<<endl; 34     return 0; 35 }
 
         

 

 

o(nlogn)寫法:


 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<map>
 7 #include<set>
 8 #include<vector>
 9 using namespace std; 10 #define ll long long
11 const int maxn=5e4+5; 12 const int inf=1e9+7; 13 //最長上升子序列
14 int dp[maxn]; 15 int num[maxn]; 16 int main() 17 { 18     ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); 19     
20     int n; 21     cin>>n; 22     
23     for(int i=0;i<n;i++) 24         cin>>num[i]; 25     
26     fill(dp,dp+n,inf); 27     
28     for(int i=0;i<n;i++) 29         *lower_bound(dp,dp+n,num[i])=num[i]; 30     
31     cout<<lower_bound(dp,dp+n,inf)-dp<<endl; 32     
33     return 0; 34 }
 
         




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM