hdu 4604 Deque(最长不下降子序列)

从后向前对已搜点做两遍LIS(最长不下降子序列),分别求出已搜点的最长递增、递减子序列长度。这样一直搜到第一个点,就得到了整个序列的最长递增、递减子序列的长度,即最长递减子序列在前,最长递增子序列在后,得到题目所求的双端队列的最长不下降子序列。

注意要去重,当发生替换之后,同种元素在两个序列中的数量不同。为得到最长序列,当然是把少的去掉,留下多的。

5

2 1 2 2 3

 1 #include<stdio.h>
 2 #include<cstring>
 3 #include<vector>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 const int MAXN=111111;
 8 
 9 vector<int>v1;
10 vector<int>v2;
11 
12 int a[MAXN];
13 
14 int main()
15 {
16     int T,n,i;
17     int len1,len2,same,ans;
18     scanf("%d",&T);
19     while(T--)
20     {
21         ans=0;
22         scanf("%d",&n);
23         for(i=0;i<n;i++)
24             scanf("%d",&a[i]);
25         v1.clear();
26         v2.clear();
27         for(i=1;i<=n;i++)
28         {
29             int c=lower_bound(v1.begin(),v1.end(),a[n-i])-v1.begin();
30             int b=upper_bound(v1.begin(),v1.end(),a[n-i])-v1.begin();
31             if(b==v1.size())
32                 v1.push_back(a[n-i]);
33             else
34                 v1[b]=a[n-i];
35             len1=b+1;
36             same=b-c+1;
37 
38             c=lower_bound(v2.begin(),v2.end(),-a[n-i])-v2.begin();
39             b=upper_bound(v2.begin(),v2.end(),-a[n-i])-v2.begin();
40             if(b==v2.size())
41                 v2.push_back(-a[n-i]);
42             else
43                 v2[b]=-a[n-i];
44             len2=b+1;
45             same=min(same,b-c+1);//去重
46             ans=max(len1+len2-same,ans);
47         }
48         printf("%d
",ans);
49     }
50     return 0;
51 }
View Code
原文地址:https://www.cnblogs.com/zstu-abc/p/3221067.html