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;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)