c++ M - Zigzag Gym - 101291M SDUT

在这里插入图片描述
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 InputSample Output
54
2 1 3 4 2

题目大意:在一个序列中求出曲折序列,曲折序列:两个元素严格按照递增递减交替出现,对于第一组元素可以是递增的也可以是递减的,但是这里的曲折序列并不是必须连续的,样例中的答案就应该是2 1 3 2 (递减递增递减)一共四个元素

解题思路:
用到的变量:使用a数组储存原数据,len1储存到该元素为递减的曲折序列的最长长度,len2储存到该元素为递增的曲折序列的最长长度
然后是用动态规划的思想
1.首先初始化len1,len2全部为1
在这里插入图片描述
2.从第二个元素开始找,先更新len1中的值,len1中的值为到该元素为递减的曲折序列,所以需要找在该元素之前的递增的曲折序列中最长的即找在len2中该元素之前的最大值。

      if (a[i] < a[j] && len1[i] < len2[j] + 1)
      {
          len1[i] = len2[j] + 1;
      }

同理:在更新len2中的值时,需要找len1中该元素之前的最大值,并以此类推。

    if (a[i] > a[j] && len2[i] < len1[j] + 1)
    {
         len2[i] = len1[j] + 1;
     }

第二个元素更新后
在这里插入图片描述

第三个元素更新后
在这里插入图片描述
第四个元素更新后
在这里插入图片描述
第五个元素更新后
在这里插入图片描述
3.找出len1和len2中的最大值

// Zigzag.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <bits/stdc++.h>

using namespace std;

int main()
{
    int n, a[52], len1[52], len2[52];
    cin >> n;
    for (int i = 0; i < n; i++)
    //输入数据,并初始化len1,和len2
    {
        cin >> a[i];
        len1[i] = len2[i] = 1;
    }
    
    //动态规划,求最长曲折序列
    for (int i = 1; i < n; i++)
    {
        for (int j = i - 1; j >= 0; j--)
        {
        //求到该元素为递减的曲折序列的最长长度
            if (a[i] < a[j] && len1[i] < len2[j] + 1)
            {
                len1[i] = len2[j] + 1;
            }
         //求到该元素为递增的曲折序列的最长长度
            if (a[i] > a[j] && len2[i] < len1[j] + 1)
            {
                len2[i] = len1[j] + 1;
            }
        }
        
    }
    int Max = 0;//找最大值
    for (int i = 0; i < n; i++)
    {
        if (Max < len1[i])
        {
            Max = len1[i];
        }
        if (Max < len2[i])
        {
            Max = len2[i];
        }
    }
    cout << Max << endl;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

碧羽o(* ̄▽ ̄*)ブ回雪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值