题目来源: http://acm.pku.edu.cn/JudgeOnline/problem?id=3298
 这到题目显然是一道DP题。
设:在求的数列中,如果这个数比左右的数大,则称为大值,反之为小值。 
原先想到的是,对于每个数,设置2个值,一个为小值一个为大值。小值为前面所有比此数大的数的大值加1,如果为0个不用加了,因为第一个数必须为大值.大值为前面所有比此数小的数的小值+1.这个算法的时间复杂度为O(n^2)。TLE。
参考 大牛们的代码。设置2个值,mi,mx。表示一个数的为小值,和大值时串的长度。显然一个大值和小值的串的长度是相互递增的。即mi=max(mi,mx+1),
mx=max(mi+1,mx);设置一个标号值pre表示前一个值。比较当前值,如果小,则当前值为大值是的串长一定不会变化。只需要比较为小值时,串是否变化就行。反之同理。 
其实这道题也就是求一串数组成的w型的拐角有多少个。并不需要关系具体是那几个数组成这样的拐角。
代码:
TLE版:
 

Code
 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 int num[30001][2];
 6 int nn[30001];
 7 int n;
 8 
 9 int Max(int a,int b)
10 {
11     return a>b?a:b;
12 }
13 
14 int main()
15 {
16     freopen("test.txt","r",stdin);
17     int t;
18     cin>>t;
19     while(t--)
20     {
21         scanf("%d",&n);
22         for(int i=0;i<n;i++) scanf("%d",&nn[i]);
23         num[0][0]=0;num[0][1]=1;
24         int m1=0,m2=0,mmx=1;
25         for(int i=1;i<n;i++)
26         {
27             m1=0,m2=0;
28             for(int j=i-1;j>=0;j--)
29             {
30                 if(nn[j]<nn[i]) m1=Max(m1,num[j][0]);
31                 if(nn[j]>nn[i]) m2=Max(m2,num[j][1]);
32             }
33             num[i][0]=m2==0?m2:m2+1;num[i][1]=m1+1;
34             mmx=Max(num[i][0],mmx);mmx=Max(num[i][1],mmx);
35         }
36         printf("%d\n",mmx);
37     }
38 } 
 
 
AC版: 
 

Code
 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 int Max(int x,int y)
 6 {
 7     return x>y?x:y;
 8 }
 9 
10 int n,pre;
11 
12 int main()
13 {
14     int t;
15     cin>>t;
16     while (t--)
17     {
18         scanf("%d%d",&n,&pre);
19         int u=-n,d=0,x;
20         for(int i=1;i<n;i++)
21         {
22             scanf("%d",&x);
23             if(x<pre) u=Max(u,d+1);
24             if(x>pre) d=Max(u+1,d);
25             pre=x;
26         }
27         printf("%d\n",Max(u,d)+1);
28     }
29 }