eoj2083 DP

ZigZag

Time Limit:1000MSMemory Limit:30000KB
Total Submit:257Accepted:106

Description

A sequence of numbers is called a zig-zag sequence if the differences between successive numbers strictly alternate between positive and negative. The first difference (if one exists) may be either positive or negative. A sequence with fewer than two elements is trivially a zig-zag sequence.
For example, 1,7,4,9,2,5 is a zig-zag sequence because the differences (6,-3,5,-7,3) are alternately positive and negative. In contrast, 1,4,7,2,5 and 1,7,4,5,5 are not zig-zag sequences, the first because its first two differences are positive and the second because its last difference is zero.


-sequence contains between 1 and 50 elements, inclusive.
-Each element of sequence is between 1 and 1000, inclusive.

Input

Given a sequence of integers, sequence, return the length of the longest subsequence of sequence that is a zig-zag sequence. A subsequence is obtained by deleting some number of elements (possibly zero) from the original sequence, leaving the remaining elements in their original order.

Output

output the length of the longest subsequence of sequence that is a zig-zag sequence.

Sample Input

6
1 7 4 9 2 5

/*
10
1 17 5 10 13 15 10 5 16 8
*/

Sample Output

6

/*
7
*/


题目:EOJ2083

 

题目分析:思路类似求最长上升子序列。需要注意的是是否满足zag—tag还需考察一个点的前一个zag_tag串的值,故应保存每个节点的直接前驱节点的。用dp[i].val表示以i节点结尾的zag_tag串的最大值,用dp[i].pre表示i节点在zag_tag串中前一个节点的值,若i为zag_tag串的首节点则置dp[i].pre=-1.则有:对点i,令j为0至i-1;1.若dp[j].pre=-1,则只需考察i和j节点值是否相等,更新dp[i]的值,2.若dp[j].pre不等以-1,则比较a[j]-a[dp[j].pre])*(a[j]-a[i])和0的大小,可更新dp[i]的值。最后遍历dp可得最大值。

 

AC代码:

#include <iostream>

#include <cstring>

 

using namespace std;

 

struct Node

{

   int val,pre;

}dp[55];

 

int main()

{

   int n,a[55]={},i,j;

   memset(dp,0,sizeof(dp));

   for(i=0;i<55;++i)

       dp[i].pre=-1;

   cin>>n;

   for(i=0;i<n;++i)

       cin>>a[i];

   if(n==1)

       cout<<"1"<<endl;

   else if(n==2)

    {

       if(a[1]!=a[0])

           cout<<"2"<<endl;

       else

           cout<<"1"<<endl;

    }

   else

    {

       dp[0].val=1;

       dp[0].pre=-1;

       for(i=1;i<n;++i)

       {

           for(j=0;j<i;++j)

           {

                if(dp[j].pre==-1)

               {

                    if(a[i]!=a[j])

                    {

                       if(dp[i].val<=dp[j].val)

                        {

                           dp[i].val=dp[j].val+1;

                            dp[i].pre=j;

                        }

                    }

                }

                else

                {

                    if((a[j]-a[dp[j].pre])*(a[j]-a[i])>0 )

                    {

                       if(dp[i].val<=dp[j].val)

                        {

                           dp[i].val=dp[j].val+1;

                            dp[i].pre=j;

                        }

                    }

                }

           }

       }

       int ans=0;

       for(i=0;i<n;++i)

           ans=max(ans,dp[i].val);

       cout<<ans<<endl;

    }

   return 0;

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值