首页 > 其他分享 >学习笔记#5:单调队列优化&斜率优化

学习笔记#5:单调队列优化&斜率优化

时间:2024-02-18 21:47:05浏览次数:18  
标签:队列 sum 2Asum 斜率 优化 单调

学习笔记#5:单调队列优化&斜率优化

单调队列

首先要搞懂什么是单调队列。

单调队列是一种求区间最值问题的一种方式,与其他 RSQ 问题的求解方法不同的是,它更善于解决滑动窗口式的 RSQ 问题,一般来说,假设我们要维护最大值,则需维护一个单调递减的队列,这样队首最大,每次取队首即可。而当队首不在我们的讨论范围中时,就将它弹出。每次便利到新元素时,从队尾依次向前弹出,知道符合单调队列的性质时再将其加入。

注意,队列维护的不是数组的值,而是下标,这样才方便确定是否满足讨论范围。

每个元素分别出入队一次,所以复杂度 \(\text{O}(n)\)。

例:P1886 滑动窗口 /【模板】单调队列

有一个滑动的窗口,大小固定,每次取窗口中的最大值:
样例:

8 3
1 3 -1 -3 5 3 6 7

建立一个单调队列,维护单调递减:

int Q[maxn], head, tail;
for(int i = 1; i <= n; i++) {
	while(head < tail and Q[head] < i - k + 1) head++;//不在讨论范围内就出队
	while(head < tail and a[i] >= Q[tail]) tail--;//维护单调递减
	Q[++tail] = i;
	if(i >= k) ans[++ca] = Q[head];
}

以上就是单调队列。

单调队列优化DP

所谓单调队列优化,指的是用单调队列优化 DP。

我们经常看到这样的式子:

\(f[i] = min(f[j] + a[i] + b[j]) (L(i) \le j \le R(i))\)

如果暴力转移就是 \(\text{O}(n^2)\) 的复杂度,对于 \(1e6\) 的数据并不友好。

这时我们用单调队列维护 \(f[j] + b[j]\) 的最值, 就可以将复杂度压到 \(\text{O}(1)\) 了。

斜率优化

引入

斜率优化其实是一种特殊的单调队列优化。

我们有时也会遇到这样的式子:

\(f[i] = max(f[j] + val(i, j))\)

其中 \(val(i, j)\) 同时与 \(i\)、\(j\) 有关,无法直接用单调队列进行优化。

例:P3628 [APIO2010] 特别行动队

设 \(f[i]\) 表示以 \(i\) 为某一段的结尾,前面总得分的最大值。转移方程显然:

\(f[i] = max(f[j] + a \times (sum[i] - sum[j])^2 + b \times (sum[i] - sum[j]) + c)\)

继续化:
\((f[i] + Asum[i]^2 - Bsum[i]) + sum[j] \times 2Asum[i] = f[j] + Asum[j]^2 - Bsum[j] + c\)
我们发现中间有个难以处理的 \(sum[j] \times 2Asum[i]\),该怎么处理呢?

于是请出今天的主角:斜率优化。

原理

转化式子

我们把只与 \(j\) 有关的整个式子写成 \(J\),把只与 \(i\) 有关的整个式子写成 \(I\),于是式子变成:

\(J = 2Asum[i] \times sum[j] + I\)

不难发现这是一个一次函数,\(J\) 是因变量,\(I\) 是截距,同时我们把 \(sum[j]\) 指定为自变量,那么 \(2Asum[i]\) 就是斜率。

而我们的 \(J\) 、\(2Asum[i]\)、\(sum[j]\) 均已知,只有 \(I\) 中的 \(f[i]\) 需要求出,而要使 \(f[i]\) 最大,则要使 \(I\) 最大,即截距最大。

因此我们可以将这个决策点看做一条直线,并且要求它的截距最大。

而我们的斜率是一直增大的,那么什么样的点会有可能是决策点呢?

答案是在一个上凸包中的点。

因为如果在凸包内,截距无论如何也不会比在凸包上的点更大。

因此问题就转换成了如何维护一个上凸包。

维护凸包

首先,点的横坐标 \(sum[j]\) 单调递增,因此每次新加入的决策点都在最右侧,我们判断它在凸包上还是在凸包内即可。

那么我们维护一个单调队列,当队尾和队尾前面的点的斜率的大于新点和队尾的斜率的时,这个新点才在凸包上,否则就要一直弹队尾,直到满足要求。

对于队首,如果当前斜率 \(2Asum[i]\) 的小于队首和第二个点的斜率的,那么队首也就没用了,因为后面的点切出来的截距绝对比他大,所以出队。

至此,斜率优化的全过程已展示完毕。

标签:队列,sum,2Asum,斜率,优化,单调
From: https://www.cnblogs.com/Crystal-Matrix-Ingot/p/18020004

相关文章

  • 如果由于大量数据插入数据库导致数据库性能持续下降问题?该如何进行性能优化?
    有些操作会使数据库的性能下降,MySQL是一种常用的关系型数据库管理系统,性能下降可能是由索引问题、查询语句问题、数据更新问题、锁竞争、配置参数问题、硬件资源问题或者慢查询等多种因素引起的。针对具体情况进行分析和优化可以提高MySQL的性能。本文主要介绍MySQL数据库当大量数......
  • 索引优化-失效
     1)like"%",避免使用模糊查询;尽量使用右模糊,例:like"张%";2)避免使用in,notin,连续条件可使用between...and...;3)避免使用or,可用union代替;4)避免使用null判断,可给字段添加默认值0;5)避免where=左侧进行表达式、函数操作;可更改为=右侧;6)数据量大时,避免......
  • SQL优化
     SQL执行过程:连接建立:应用程序连接数据库:应用程序通过数据库客户端与数据库服务器建立连接。认证和授权:数据库服务器验证应用程序的身份,并根据其权限确定其是否可以执行特定的SQL操作。SQL解析:SQL解析:数据库服务器接收到应用程序发送的SQL语句,对其进行解析,检......
  • 简洁高效的短链接:优化互联网体验
    在互联网时代,我们经常遇到需要分享长网址的情况。长网址不仅不美观,而且容易出错或难以记忆。为了解决这个问题,短链接应运而生。本文将介绍短链接的概念、优势以及在互联网体验中的应用,帮助读者更好地了解并利用短链接。短链接|一个覆盖广泛主题工具的高效在线平台(amd794......
  • RabbitMQ 使用细节 → 优先级队列与ACK超时
    开心一刻今天坐在太阳下刷着手机老妈走过来问我:这么好的天气,怎么没出去玩我:我要是有钱,你都看不见我的影子老妈:你就不知道带个碗,别要边玩?我:......优先级队列说到队列,相信大家一定不陌生,是一种很基础的数据结构,它有一个很重要的特点:先进先出但......
  • dp的优化(单队,斜率)
    1.单调队列优化\(dp\)维护最小值:\(x\leqslantq.tail()\)维护最大值:\(x\geqslantq.tail()\)其实原理不难,当\(dp\)的转移源头是一个区间时,往往使用单调队列来维护区间最值(一般队列里装下标以方便维护区间大小,但也只是一般情况),节省了处理区间的时间(甚至噶掉一维),重点是对区间的......
  • Unity手机游戏性能优化系列:针对CPU端的性能调优
    做手机游戏开发的时,经常会遇到手机游戏的性能问题,手机游戏的性能问题可能有很多的方面,今天我们从CPU调优的角度来給大家介绍一下常用的CPU调优的一些经验和手段。这些经验和手段都有可能随着时间与环境的变化改变而改变,具体还是要以实际的为准,先定位性能问题,再上具体的手段。接下......
  • 【集训笔记】2024 寒假集训 第一天:最优化问题
    最优化问题二分许多最优化问题可以通过二分来转化为判定性问题。0-1分数规划0-1分数规划思想用于求解分式最优化问题。可以通过对分式二分判定,转化为某一式子大于/小于常数,然后求对应最值即可。动态规划动态规划算法的一大用处就是解决最优化问题。朴素的动态规划效率一般......
  • DNS解析与优化
    这篇笔记总结自网课......
  • DP 优化
    DP优化一些典型或者不典型的DP优化实例。CF354DTransferringPyramid题意:有一个\(n\)层的金字塔,现在能进行两种操作,一是给某个点染色,代价是3,或者画一个底边是金字塔底边的子三角形,给每个点,代价是点数+2,要求用最小代价覆盖所有要染色的\(m\)个点。思路:定义\(h_i\)表......