题目描述
给定一个长度为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 }