单调队列或单调栈的学习及认识
。。。顾名思义,数据是具有某方面的单调性质的(单增或单减等)。单调队列一般是用于优化动态规划方面问题的一种特殊数据结构,且多数情况是与定长连续子区间问题相关联。
一、数据结构的认识
1.双端队列deque
双端队列是一种线性表,遵守先进先出的原则。其支持下面四种操作:
(1)从队首删除
(2)从队尾删除
(3)从队尾插入
(4)查询线性表中任一元素的值
2.单调队列
单调队列是种特殊双端队列,其内部元素具有单调性。最常用的是最大队列与最小队列,其内部元素分别单增或单减。
有如下操作:
(1)插入:若新元素从队尾插入会破坏单调性,则删除队尾元素,直到不在破坏单调性为止,再将其加入单调队列尾。
(2)获取最优(max,min)值:访问队首元素。
二、例题
1.自愿者选拔
题目大意:有一群自愿者陆陆续续的来排队,队首的人在某些时刻才会离开,每个人有一个int型的人品值,现在就问在当前队列中人品最大的是多少,没有的话输出-1.
1.C name rp 名字为name人品为rp的人排到队尾
2.G 队首的人出队
3.Q 询问当前队列中rp最高的
分析:这个就是一个连续区间最大值的问题。这时单调队列里面的人出了先后顺序是单增的,其rp是单减的(head to tail)。用一个out变量记录目前出队了多少人,in记录进来了多少了,
当某次询问时,如果out <= in时,显然输出-1,不然就输出队首的人的rp值。
因为队列里面做调整的时候,对首的人原位置并不是第一,所以要记录些这个每个人的原位置。这样就可以O(n)的解决这个问题了。
const int maxn = 1e6 + 10;
struct node {
char *name;//名字
int rp;//rp值
int pos;//原队列中的位置
node() {}
node(char c[], int rp,int pos) {
this->name = c;
this->rp = rp;
this->pos = pos;
}
}p[maxn];
int main(int argc, const char * argv[])
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int t;
cin >> t;
char name[10];
int rp;
while(t--) {
char op[10];