最长递增长度 (最长上升子序列)
题目描述
给定一个长度为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 }
大佬见笑,,