解析:
由题目分析可知,双端队列中一定存在下面性质
所以我们要给原数组从小到大排序,判断他们能组成多少个这样的峰谷
但是有这么一个问题就是出现重复的数,那么他们下标的排列有可能是峰谷
例如:5,1,6或者是5,4,3
这样就不好统计峰谷了,最优我们肯定把这些相等的数的下标变成峰谷。
所以我们一开始假设我们是下降的,每次找出像等一段的最小下标和最大下标
判断当前数是接在后面,继续保持下降(当然题目要求最少的双端队列,要下降的就必须下降)
如果不能下降了,那我们就上升。
#include<bits/stdc++.h>
using namespace std;
#define x first
#define y second
const int N=2e5+1000;
typedef pair<int,int> PII; //排序时比较第一关键字,如果第一关键字相等。比较第二关键字
PII a[N];
int n;
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i].x,a[i].y=i;
sort(a+1,a+1+n);
int res=1;//一开始下降的 所以方案数+1
for(int i=1,j=1,last=n+1,dir=-1;i<=n;)
{
while(j<=n&&a[i].x==a[j].x) j++;//找出相等的最小和最大下标
int minp=a[i].y,maxp=a[j-1].y;
if(dir==-1)//下降
{
if(last> maxp) last=minp;
else
{
dir=1;
last=maxp;
}
}
else//上升
{
if(last<minp) last=maxp;
else
{
dir=-1;//要改变成下降,方案+1
res++;
last=minp;
}
}
i=j;
}
cout<<res<<endl;
}