【队列】【例题向】双端队列

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_42725189/article/details/102621689
  • 题目链接双端队列
  • 题目描述:用双端队列维护一个数列,只能在队首队尾插数,最后首尾合并所有队列,问多少个双端队列才能完成一次排序。
  • 思路:肯定不能依次顺推,因为有后效性。从题目结果往处理过程反向思考,先排序,观察数组下标,发现双端队列存的是单谷序列,注意相同大小的数是可以互换的,问题变为最少要分多少区块,然后贪心分区块就行了。
    代码实现
#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);
}

猜你喜欢

转载自blog.csdn.net/qq_42725189/article/details/102621689