UVa 10534 波浪子序列(快速求LIS)

https://vjudge.net/problem/UVA-10534

题意:
给定一个长度为n的整数序列,求一个最长子序列(不一定连续),使得该序列的长度为2k+1,前k+1个数严格递增,后k+1个数严格递减。

思路:

先正着求一遍LIS,再反着求一遍LIS。

当然求法是得采用O(nlogn)的求法,这个网上有很多解释,我就不多介绍了。

最后的话枚举一遍就可以了,详见代码。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<sstream>
 6 #include<vector>
 7 #include<stack>
 8 #include<queue>
 9 #include<cmath>
10 #include<map>
11 using namespace std;
12 typedef long long LL;
13 typedef pair<int,int> pll;
14 const int INF=0x3f3f3f3f;
15 const int maxn=10000+5;
16 
17 int n;
18 int a[maxn],r_a[maxn],g[maxn],d1[maxn],d2[maxn];
19 
20 int main()
21 {
22     //freopen("D:\input.txt","r",stdin);
23     while(~scanf("%d",&n))
24     {
25         for(int i=0;i<n;i++)
26         {
27             scanf("%d",&a[i]);
28             r_a[n-i-1]=a[i];
29         }
30 
31         int ans1=0;
32         for(int i=1;i<=n;i++)  g[i]=INF;
33         for(int i=0;i<n;i++)
34         {
35             int k=lower_bound(g+1,g+n+1,a[i])-g;
36             d1[i]=k;   //记录了前i个数的最长子序列
37             g[k]=a[i];
38             ans1=max(ans1,d1[i]);
39         }
40 
41         int ans2=0;
42         for(int i=1;i<=n;i++)  g[i]=INF;
43         for(int i=0;i<n;i++)
44         {
45             int k=lower_bound(g+1,g+n+1,r_a[i])-g;
46             d2[i]=k;
47             g[k]=r_a[i];
48             ans2=max(ans2,d2[i]);
49         }
50         
51         //枚举递增和递减的分隔点
52         int ans=0;
53         for(int i=0;i<n;i++)
54         {
55             int temp=min(d1[i],d2[n-i-1]);
56             temp=2*(temp-1)+1;
57             if(ans<temp)  ans=temp;
58         }
59         printf("%d
",ans);
60     }
61     return 0;
62 }
原文地址:https://www.cnblogs.com/zyb993963526/p/6920766.html