单调队列与单调栈(入门)

这些知识总算啃掉了...

重要的思路就是加入栈和队列时还要加入元素的坐标位置。

使用单调栈可以找到元素向左遍历第一个比他小的元素,也可以找到元素向左遍历第一个比他大的元素。

单调栈就简单点,只有栈顶可以操作,若要找到从左到右第一个比i大的数,就保证严格递减,这样如果到第一个比i大的数是i就会被弹出,总之就是找什么条件的数,第i个数被弹出栈的条件就是什么,建议手打栈,代码如下:

n=read();
    for(int i=1;i<=n;i++) a[i]=read();
    for(int i=1;i<=n;i++)
    {
        while(top>=1&&a[i]>=q[top].s) ans=ans+i-q[top--].id-1;
        q[++top].id=i;q[top].s=a[i]; 
    }
    for(int i=top;i>=1;i--) ans=ans+n-q[top--].id;

单调队列除了tail需要更新,还需要更新head,也就是及时把不符合信息的head出队,、

单调队列性质:

  • 1、维护区间最值
  • 2、去除冗杂状态 如上题,区间中的两个元素a[i],a[j](假设现在再求最大值)
    若 j>i且a[j]>=a[i] ,a[j]比a[i]还大而且还在后面(目前a[j]留在队列肯定比a[i]有用,因为你是往后推, 核心思想 !
  • 其中第二条对动态规划仍使用...

与题目联系时,记得把要求的元素放在队头就行了.

例:

for(int i=1;i<=k;i++)
    {
        while(head<=tail&&q[tail].s>=a[i]) tail--;
        q[++tail].id=i,q[tail].s=a[i];
    }
    mn[++o]=q[head].s;
    for(int i=k+1;i<=n;i++)
    {
        while(head<=tail&&q[tail].s>=a[i]) tail--;
        q[++tail].id=i,q[tail].s=a[i];
        while(q[head].id<=i-k) head++;
        mn[++o]=q[head].s;
    }

...

转载于:https://www.cnblogs.com/gcfer/p/10598916.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值