最长递增长度 (最长上升子序列)


最长递增长度

题目描述

给定一个长度为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