单调队列优化DP

2 篇文章 0 订阅

题目要求:一般和dp一样,不过用普通dp会T,其中dp有一维可以用单调队列优化

可以用单调队列优化的数值会出现明显的上位替代,比如:最近的最大值,最近的最大总和,耀骑士(不是)。

例子:1.输入一个长度为 n 的整数序列,从中找出一段长度不超过 m 的连续子序列,使得子序列中所有数的和最大。

原本暴力复杂度O(nm),但是由前缀和s[i]-s[j]发现,在i固定的情况下,s[j]越小越好,并且离i越近越好,这样就出现了上位替代。可以用单调队列优化。

2.农场有编号连续的n头奶牛,每头奶牛i有一个效率Ei,不能选择k头以上连续的奶牛,问最大效率。

易得,f[i]= f[i-j-1]+s[i]-s[i-j],可以发现,在i固定的情况下,f[i-j-1]-s[i-j],越大越好,并且离i越近越好,于是用单调队列优化(i-j范围(i-k~i),于是用单调队列存上位的i)

3.有按顺序排列的n个地方,初始没油,给定每个点的油,和到下一站需要的油,问从每个点出发,能不能环绕一圈(i~i+n)

令 本地油[i]-下一站花油[i]的前缀和为s[i],从i开始的一段路,剩油为s[i~i+n]-s[i-1],可用单调队列存s[i~i+n]的最小值s[k],诺s[k]-s[i-1]>=0则可以绕一圈

4.给a*b的矩阵,问n*n的范围里的max减min的最小值为多少?

预处理,对行,单调队列处理mx[i]为mx[i~i-n]范围里的最大值,对mx[i]按列处理一次,得n*n的最大值,复杂度O(a*b),最小值同理,就可得答案。


int q[N];
void get_min(int a[], int b[], int tot)
{
    int hh = 0, tt = -1;
    for (int i = 1; i <= tot; i ++ )
    {
        if (hh <= tt && q[hh] <= i - k) hh ++ ;
        while (hh <= tt && a[q[tt]] >= a[i]) tt -- ;
        b[i] = a[q[hh]];
        q[ ++ tt] = i;
        //b[i] = a[q[hh]];也可能在这里
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值