求解最长的波动序列

题目:

Description

有一个长度为N的整数序列,序列里面的数是两两不同的,现在要在里面找一个波动序列,这个序列越长越好。

比如有波动序列{a0,a1,a2an},a0 > a1 < a2 > a3 < 

Input

第一行输入一个数T,代表有T个任务,T不大于50

对于每个任务,输入格式为

N a0 a1 a2  aN 

其中N<=30000,测试数据保证序列的数两两不同。

Output

对于每个任务,输出最长的波动序列长度

Sample Input

45 1 2 3 4 55 5 4 3 2 15 5 1 4 2 35 2 4 1 3 5

Sample Output

1253
题目大意:

     本题求解最长的波动序列,只要求a0>a1<a2......,并且题目中已经明确表示不存在两个数相等,所以不用考虑两个数相等的情况,因为N的最大值为3000,如果使用两重for循环,肯定会超时,所以以下求解为用一重for循环来求解。例如一串数(9)1,8,6,10,5,3,4,2;假如不包括数字9,则第一个数应该从8开始,因为1<8,所以只能从8开始,8也可以看做一个高点,接下来为6,6看做一个低点,接下来为10一个高点,接下来为5一个低点,因为3<5,所以最低点应该是3,接着为4,到现在,我们可以得到一串数字:8,6,10,3,4,2.高点为8,10,4,低点为6,3,2,虽然5为一个低点,但是3比5小,所以低点为3,最长的串为3+3=6;由此可以看出,只要计算出这个数字串的高点和低点即可。

程序代码如下:

#include<iostream>
using namespace std;


int a[30005]={0};
int main()
{
int T;
cin>>T;
while(T--)
{
int N;
cin>>N;
int i;
for(i=0;i<N;i++)
{
cin>>a[i];
}
int front=0,real=0;                          计算最高点和最低点,front为高点计数,real为低点计数
   int high;
if(a[0]>a[1])                                    判断前两个数的大小,初步确定高低点
{
front++;
real++;
high=a[1];
}
else
{
front++;
high=a[1];
}
for(i=2;i<N;i++)
{
if((front+real)%2)                          判断接下来一个数为">"还是小于"<",此处为“<”;
{
if(a[i]>high)
{
high=a[i];
}
else
{
high=a[i];
real++;
}
}
else
{
if(a[i]>high)
{
high=a[i];
front++;
}
else
{
high=a[i];
}
}
}
cout<<front+real<<endl;
}
return 0;
}

解题感想:

    这道题当初拿起来看是,就直接去找模板去了,可是找了好长时间还是没有,修改模板也不行,还是学长要把这道题讲完的时候画的一个图,让我知道了怎么来做这道题,其实这道题跟找一个数组中最大的递减数列不一样,那道题还是有模板的,这道题还是第一次遇到,不过还好现在就解决了,以后遇到类似的题目,可以直接来解决了。这道题的解题思路主要是画出一个上下波动的线段即可。这样就可以看出来了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值