类似于最长不降子序列。
找到最长的大小相间的子序列。
dp[k] 表示一个结构体,以k号结尾的最长zig-zag子序列长度,和期待下一个数是大还是小。
struct node{
int len, state; //state, 0表示下一个数必须大,1表示必须小,2表示都可以
}
状态转移方程
dp[k].len = max( num[k]能接到dp[i]后面 ? dp[i].len+1 : 1 ), 0<=i<=k-1
边界
dp[0].len = 1;
dp[0].state = 2;
处理顺序
从左往右
#include <cstdio>
struct node{
int len, state;
};
int main(){
int n, ans = 1;
scanf("%d", &n);
int num[n];
for(int i=0; i<n; i++) scanf("%d", &num[i]);
node dp[n];
dp[0].len = 1;
dp[0].state = 2;
for(int i=1; i<n; i++){
dp[i].len = -1;
for(int j=0; j<i; j++){
node temp;
if(dp[j].state==0){
if(num[i]>num[j]){
temp.len = dp[j].len+1;
temp.state = 1;
}
else{
temp.len = 1;
temp.state = 2;
}
}
else if(dp[j].state==1){
if(num[i]<num[j]){
temp.len = dp[j].len+1;
temp.state = 0;
}
else{
temp.len = 1;
temp.state = 2;
}
}
else{
if(num[i]>num[j]){
temp.len = dp[j].len + 1;
temp.state = 1;
}
else if(num[i]<num[j]){
temp.len = dp[j].len + 1;
temp.state = 0;
}
else{
temp.len = 1;
temp.state = 2;
}
}
if(temp.len > dp[i].len) dp[i] = temp;
}
if(dp[i].len > ans) ans = dp[i].len;
}
printf("%d", ans);
return 0;
}