版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
- 题目链接:双端队列
- 题目描述:用双端队列维护一个数列,只能在队首队尾插数,最后首尾合并所有队列,问多少个双端队列才能完成一次排序。
- 思路:肯定不能依次顺推,因为有后效性。从题目结果往处理过程反向思考,先排序,观察数组下标,发现双端队列存的是单谷序列,注意相同大小的数是可以互换的,问题变为最少要分多少区块,然后贪心分区块就行了。
代码实现:
#include<bits/stdc++.h>
using namespace std;
struct node{
int v,id;
}x[200005];
bool cmp(node a,node b)
{
return a.v<b.v;
}
int n,mi[200005],mx[200005],zz,dn=0,ans=0;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&x[i].v),x[i].id=i;
sort(x+1,x+1+n,cmp);
for(int i=1;i<=n;i++)
{
if(i==1||x[i].v!=x[i-1].v)
{
++zz;
mi[zz]=x[i].id;
mx[zz]=x[i].id;
}
if(x[i].id<mi[zz])mi[zz]=x[i].id;
if(x[i].id>mx[zz])mx[zz]=x[i].id;
}
int lj=9999999;
for(int i=1;i<=zz;i++)
{
if(dn)
{
if(mx[i]<lj)
{
lj=mi[i];
continue;
}
dn=0;
lj=mx[i];
continue;
}
if(mi[i]>lj)
lj=mx[i];
else
{
ans++;
dn=1;
lj=mi[i];
}
}
printf("%d",ans);
}