lightoj 1421 Wavio Sequence (最长严格单峰子序列)

来源:互联网 发布:藤井莉娜开的淘宝店铺 编辑:程序博客网 时间:2024/04/29 19:39
Wavio Sequence
Time Limit: 4 second(s)     Memory Limit: 32 MB

Wavio is a sequence of integers. It has some interesting properties:
1.      Wavio is of odd length i.e. L = 2*n + 1.
2.      The first (n+1) integers of Wavio sequence make a strictly increasing sequence.
3.      The last (n+1) integers of Wavio sequence make a strictly decreasing sequence.
4.      No two adjacent integers are same in a Wavio sequence.
For example 1, 2, 3, 4, 5, 4, 3, 2, 1 is an Wavio sequence of length 9. But 1, 2, 3, 4, 5, 4, 3, 2, 2 is not a valid wavio sequence. In this problem, you will be given a sequence of integers. You have to find the length of the longest Wavio sequence which is a subsequence of the given sequence. Consider the given sequence as:
1 2 3 2 1 2 3 4 3 2 1 5 4 1 2 3 2 2 1
Here the longest Wavio sequence is: 1 2 3 4 5 4 3 2 1. So, the output will be 9.


Input

Input starts with an integer T (≤ 12), denoting the number of test cases.

Each case starts with a line containing an integer N (1 ≤ N ≤ 105) denoting the number of elements in the sequence. The next line contains N space separated integers between -108 to 108, that form the sequence.


Output

For each case, print the case number and the length of the maximum possible Wavio sequence.

Sample Input

3
10
1 2 3 4 5 4 3 2 1 10
14
1 2 3 2 1 2 3 4 3 2 1 5 4 1
5
1 2 3 4 5
    
Output for Sample Input
Case 1: 9
Case 2: 7

Case 3: 1


题目链接:http://lightoj.com/volume_showproblem.php?problem=1421

题目大意:求最长的严格单峰子序列,单峰就是先增后减,严格就是相邻的数字不等,子序列就是选的数字不要求连续

题目分析:从左到右,从右到左分别求一次最长上升子序列,求的时候用nlogn的解法记录到当前数字所能组成的上升子序列的最大长度,比如第i个点左到右记录的为ldp[i],右到左记录的为rdp[i],答案就是2 *min(ldp[i], rdp[i]) - 1,减1是因为中间那个数字重复了一次

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int const MAX = 1e5 + 5;int n, a[MAX];int lstk[MAX], rstk[MAX];int ldp[MAX], rdp[MAX];int ltop, rtop;int main() {    int T;    scanf("%d", &T);    for(int ca = 1; ca <= T; ca ++) {        printf("Case %d: ", ca);        scanf("%d", &n);        for(int i = 0; i < n; i ++) {            scanf("%d", &a[i]);        }        ltop = rtop = 0;        for(int i = 0; i < n; i ++) {            ldp[i] = 1;            if(ltop == 0 || lstk[ltop - 1] < a[i]) {                lstk[ltop ++] = a[i];            }            else {                int pos = lower_bound(lstk, lstk + ltop, a[i]) - lstk;                lstk[pos] = a[i];            }            ldp[i] = ltop;        }        for(int i = n - 1; i >= 0; i --) {            rdp[i] = 1;            if(rtop == 0 || rstk[rtop - 1] < a[i]) {                rstk[rtop ++] = a[i];            }            else {                int pos = lower_bound(rstk, rstk + rtop, a[i]) - rstk;                rstk[pos] = a[i];            }            rdp[i] = rtop;        }        int ans = 1;        for(int i = 0; i < n; i ++) {            ans = max(ans, 2 * (min(rdp[i], ldp[i])) - 1);        }        printf("%d\n", ans);    }}


0 0