uva 10534 Wavio Sequence

题意:

给出一个数列,要求找出一个子序列,长度为2 * n + 1。

要求这个子序列的前n + 1个数为严格递增的,后n + 1个数为严格递减的。

求最长的这样一个子序列。

思路:

首先求出以每一个数结尾的最长上升子序列(从左到右)的长度inc和以每一个数结尾的最长上升子序列(从右到左)的长度dnc。

需要用nlogn的求法,不然TLE。

之后对于每一个数,子序列的长度是2 * min(inc[i],dnc[i]) - 1。

从这个里面找最大值即可。

代码:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <string>
 6 using namespace std;
 7 const int N = 10005;
 8 const int inf = 0x3f3f3f3f;
 9 int a[N];
10 int inc[N],dnc[N];
11 int ans[N];
12 int main()
13 {
14     int n;
15     while (scanf("%d",&n)!=EOF)
16     {
17         for (int i = 0;i < n;i++) scanf("%d",&a[i]);
18         memset(inc,0,sizeof(inc));
19         memset(dnc,0,sizeof(dnc));
20         int len = 1;
21         ans[len-1] = a[0];
22         inc[0] = 1;
23         for (int i = 1;i < n;i++)
24         {
25             if (a[i] > ans[len-1])
26             {
27                 ans[len++] = a[i];
28                 inc[i] = len;
29             }
30             else
31             {
32                 int pos = lower_bound(ans,ans+len,a[i]) - ans;
33                 ans[pos] = a[i];
34                 inc[i] = len;
35             }
36         }
37         dnc[0] = 1;
38         len = 1;
39         ans[len-1] = a[n-1];
40         for (int i = n - 2;i >= 0;i--)
41         {
42             if (a[i] > ans[len-1])
43             {
44                 ans[len++] = a[i];
45                 dnc[i] = len;
46             }
47             else
48             {
49                 int pos = lower_bound(ans,ans+len,a[i]) - ans;
50                 ans[pos] = a[i];
51                 dnc[i] = len;
52             }
53         }
54         int res = 0;
55         for (int i = 0;i < n;i++)
56         {
57             res = max(min(dnc[i],inc[i]) * 2 - 1,res);
58         }
59         printf("%d
",res);
60     }
61     return 0;
62 }
原文地址:https://www.cnblogs.com/kickit/p/8859336.html