达达现在碰到了一个棘手的问题,有 N 个整数需要排序。
达达手头能用的工具就是若干个双端队列。
她从 1 到 N 需要依次处理这 N 个数,对于每个数,达达能做以下两件事:
1.新建一个双端队列,并将当前数作为这个队列中的唯一的数;
2.将当前数放入已有的队列的头之前或者尾之后。
对所有的数处理完成之后,达达将这些队列按一定的顺序连接起来后就可以得到一个非降的序列。
请你求出最少需要多少个双端序列。
输入格式
第一行输入整数 N,代表整数的个数。
接下来 N 行,每行包括一个整数 Di,代表所需处理的整数。
输出格式
输出一个整数,代表最少需要的双端队列数。
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int>PII;
PII q[200011];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>q[i].first;
q[i].second=i;
}
sort(q+1,q+1+n);
int last=INT_MAX,dir=-1,maxp,minp,res=0;
for(int i=1;i<=n;)
{
int j=i;
while(j<=n&&q[j].first==q[i].first)j++;
maxp=q[j-1].second,minp=q[i].second;
if(dir==-1)
{
if(last>maxp)last=minp;
else dir=1,last=maxp;
}
else
{
if(last<minp)last=maxp;
else dir=-1,last=minp,res++;
}
i=j;
}
cout<<res;
return 0;
}
思路:最终我们是要将其排列成一个非降序的序列,求的是在排这个序列过程中最少能用多少个双端队列。首先当我们开一个新的双端队列之后再往里插值不管是头插还是尾插后来进去的数在原序列中的下标一定是比第一个打的而且越早进去的越小,所以每个双端队列里面的数的下标一定满足一个单谷,第一个插入的值的下标就是谷底,所以现在问题就转换成了当我们把这个原序列从小到大排序之后,就会形成一个下标构成的序列,姑且称为b。而在b序列中最少能出现多少个单谷即是答案。因为给的数是可能一样大的,所以我们在排序的时候是有可选择性的,只要贪心一下处理这个顺序问题就能找出最少的单谷(原谅我偷懒)