Zigzag (最长交替子序列)

Zigzag (最长交替子序列)

Your Ph.D. thesis on properties of integer sequences is coming along nicely. Each chapter is on a different type of sequence. The first covers arithmetic sequences. Subsequently you cover binomial sequences, computable sequences, decreasing sequences, and so on. You have one more chapter to write, on zigzagging sequences. A sequence is zigzagging if adjacent elements alternate between strictly increasing and strictly decreasing. The first pair of numbers can be either strictly increasing or strictly decreasing. For a given sequence, find the length of its longest zigzagging subsequence.

Input

The first line of input contains a single integer n (1 ≤ n ≤ 50), the length of the sequence. The second line contains n space-separated integers, describing the sequence. Every number in the sequence is guaranteed to be between 1 and 50, inclusive.

Output

Print, on a single line, the length of a longest zigzagging subsequence of the input sequence

 

Sample Input

5 2 1 3 4 2

Sample Output

4

Sample Input

10 1 1 1 1 1 1 1 1 1 1

Sample Output

1

 

题意:给一个序列,求最长交替子序列,就是一个大数一个小数,例如:1 5 1 5 1 5; 1 8 2 4 3 6。注:可以不连续。

思路:类似于最长上升子序列,需要开两个dp,dp1记录最长上升子序列,dp2记录最长下降子序列。 

想象一下每个点之前都连接了一条线,分为上升线和下降线。 如果是上升线那么下一次需要连接下降线的点。

例如 : 2 1 3 4 0,  其中dp1[3]=2 表示 上升线连接到了节点三,此前已经有2个点连成了拉链序列,下一步需要连接下降线。

 

代码:

#include <bits/stdc++.h>

using namespace std;

int dp1[55]; // 下降线
int dp2[55]; // 上升线
int a[55];
int n;

int main()
{
    int i,j;
    cin >> n;
    for ( i=0; i<n; i++ ) {
        cin >> a[i];
        dp1[i] = dp2[i] = 1; // 初始化为1
    }

    for ( i=0; i<n; i++ ) { // 两个for类似于最长上升子序列
        for ( j=0; j<i; j++ ) { //不懂的先去看最长上升子序列
            if ( a[j]<a[i] ) { // 这需要用一个上升线来连接两个节点。
                dp2[i] = max(dp2[i],dp1[j]+1); // 比较i的上升线 和 j的下降线+1
            }
            else if ( a[j]>a[i] ) {
                dp1[i] = max(dp1[i],dp2[j]+1); // 类上
            }
        }
    }
    int ans = 0;
    for ( i=0; i<n; i++ ) {
        ans = max(ans,dp1[i]);
        ans = max(ans,dp2[i]);
    }
    cout << ans << endl;

    return 0;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值