这里提供一种线性的贪心做法,不知道有没有问题,洛谷完全能ac,欢迎来hack我的代码。
这题显然是求一个最长波浪型的子序列,然后我们可以发现,一个连续的上升或下降序列中,有且只有一个能被选入最终的子序列中,不然就不满足波浪的需求,因此我们只需要统计连续的上升与下降序列的个数,最终的答案等于统计数+1。
另外,因为是要求严格波浪,所以对于相等的连续序列我们可以直接忽略,相当于只有一个点。
附上简短代码:
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<map> #include<queue> #define RG register #define N 100100 #define ll long long #define ld long double using namespace std; inline ll read(){ RG ll x=0,o=1; RG char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-') ch=getchar(); if(ch=='-') o=-1,ch=getchar(); while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x*o; } int main(){ int n=read(),las=read(),op=0,ans=0; //先处理一个点防炸裂,不过最好特判下n=1 //op记录上一个单调序列的种类 1是上升 2是下降 //las为上一个高度 for(RG int i=2;i<=n;++i){ int x=read(); if(x==las) continue ; //若不满足上一个序列单调性 if(op!=1&&x>las) ++ans,op=1; else if(op!=2&&x<las) ++ans,op=2; las=x; } cout<<ans+1; }