注:文中全部图片均为手绘,不喜勿喷

总论

斜率优化是dp优化中极其常用的一种手法

第一点,先要懂什么是凸包与单调队列

先来看看凸多边形是什么样

接着再是斜率及斜率优化

一、凸包及凸多边形

凸多边形

就像这样

这就不是

即所有角都 ≤ 180 \leq180 ≤180°

凸包

一条折线,满足斜率(定义看下面)单调递增或递减,例如

二、 单调队列

请看下图

三、斜率

进入正题

什么是斜率?

严谨一点讲:

斜率 k = Δ y Δ x k=\frac{\Delta y}{\Delta x} k=ΔxΔy​

其中, Δ x \Delta x Δx 与 Δ y \Delta y Δy 表示横坐标差与纵坐标差

在 Δ x \Delta x Δx 为 0 的时候,即该直线与 y y y 轴平行,该直线斜率不存在或认为趋向于 ∞

一次函数中, f ( x ) = a x + b f(x)=ax+b f(x)=ax+b,a就是其函数影像的斜率

一篇博客少不了一道题

例题——斜率

输入格式

第一行两个整数 n n n 和 m m m 。

接下来 n n n 行,每行两个整数,表示一个点的坐标。

接下来 m m m 行,每行一个整数,表示一条直线的斜率。

输出格式
对于每个斜率 k k k ,输出 k x + y kx+y kx+y 的最大值, 其中 ( x , y ) (x,y) (x,y) 是给出的 n n n 个点中的一个。

样例

输入

5 4
-1 1
1 2
3 4
4 3
5 6
-2
3
-5
10

输出

3
21
6
56

数据范围与提示

n , m n,m n,m 的范围 [ 1 , 1 0 5 ] [1,10^5] [1,105]; x , y , k x,y,k x,y,k 的范围 [ − 1 0 9 , 1 0 9 ] [-10^9,10^9] [−109,109] 。

思路

一看这题的数据范围,暴力绝对挂,必须考虑优化

首先,暴力的思想是:
a n s = max ⁡ { x i k + y i } ( 1 ≤ i ≤ n ) ans=\max\{x_ik+y_i\}(1\leq i\leq n) ans=max{xi​k+yi​}(1≤i≤n)
我们考虑舍去多余的判断

不妨先将节点按x轴排序

当 ( x j , y j ) (x_j,y_j) (xj​,yj​) 比 ( x i , y i ) ( i < j ) (x_i,y_i)~(i<j) (xi​,yi​) (i<j) 更优时候,有
k x i + y i < k x j + y j kx_i+y_i< kx_j+y_j kxi​+yi​<kxj​+yj​
k ( x j − x i ) > y i − y j k(x_j-x_i)> y_i-y_j k(xj​−xi​)>yi​−yj​
− k < y i − y j x i − x j = k j ↔ i -k<\frac{y_i-y_j}{x_i-x_j}=k_{j\leftrightarrow i} −k<xi​−xj​yi​−yj​​=kj↔i​

k x ↔ y k_{x\leftrightarrow y} kx↔y​ 表示连接 x x x 和 y y y 的线的斜率

显然,一个点只有比两侧的点更优,才可能是最优决策点

则对于每次询问的 k k k ,若点 i i i 是决策点,一定存在 k i ↔ i − 1 ≥ − k > k i + 1 ↔ i k_{i\leftrightarrow i-1}\geq -k>k_{i+1\leftrightarrow i} ki↔i−1​≥−k>ki+1↔i​

很明显,后一个的斜率 < < <前一个的斜率,是一个上凸包(如图)

这样,我们的目的变为维护一个上凸包,即斜率递减

可以利用类似单调栈的方法:遇到一个点 i i i先将其与队末连线,如果产生了一个下凸包,则删掉队末……直至满足条件。然后加入 i i i点(是类似单调栈哦!与单调栈还是不同的)

均摊复杂度 O ( 1 ) O(1) O(1)(证明:因为每个数都最多加入一次,删除一次)

循环结束后

对于每个询问,如何求出最优解?

不难发现,对于询问的 k k k,

当 k j − 1 ↔ j > − k k_{j-1\leftrightarrow j}>-k kj−1↔j​>−k,则 j j j一定是 [ 1 , j ] [1,j] [1,j]中的最优决策点

当 k j − 1 ↔ j ≤ − k k_{j-1\leftrightarrow j}\leq -k kj−1↔j​≤−k,则 j j j一定是 [ j , n ] [j,n] [j,n]中的最优决策点

每次二分答案,可做到 O ( n log ⁡ n ) O(n\log n) O(nlogn)

当然,可以利用单指针,将k从小到大排序,离线处理

证明:
因为 k k k越大,其答案斜率越小,可以往更后面处理,理论 O ( n log ⁡ n ) O(n\log n) O(nlogn)或 O ( n + p ) , p = max ⁡ { k i } ( 1 ≤ i ≤ m ) O(n+p),p=\max\{k_i\}(1\leq i\leq m) O(n+p),p=max{ki​}(1≤i≤m)

对于此题,至少 O ( n log ⁡ n ) O(n\log n) O(nlogn),即快排时间复杂度或计排 + m a p +map +map时间复杂度

二、斜率优化dp

这是斜率的升级版

依然少不了一道题

例题——[SDOI2016] 征途

题目描述

Pine开始了从S地到T地的征途。

从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站。

Pine计划用m天到达T地。除第m天外,每一天晚上Pine都必须在休息站过夜。所以,一段路必须在同一天中走完。

Pine希望每一天走的路长度尽可能相近,所以他希望每一天走的路的长度的方差尽可能小。

帮助Pine求出最小方差是多少。

设方差是v,可以证明, v × m 2 v\times m^2 v×m2是一个整数。为了避免精度误差,输出结果时输出 v × m 2 v\times m^2 v×m2。

输入格式

第一行两个数 n、m。

第二行 n 个数,表示 n 段路的长度

输出格式

一个数,最小方差乘以 m 2 m^2 m2 后的值

样例 #1

样例输入 #1

5 2
1 2 5 8 6

样例输出 #1

36

提示

对于 30 % 30\% 30% 的数据, 1 ≤ n ≤ 10 1 \le n \le 10 1≤n≤10

对于 60 % 60\% 60% 的数据, 1 ≤ n ≤ 100 1 \le n \le 100 1≤n≤100

对于 $100% $ 的数据, 1 ≤ n ≤ 3000 1 \le n \le 3000 1≤n≤3000

保证从 S S S 到 T T T 的总路程不超过 30000 30000 30000 。

思路

  • 第一步:方差这个东西好玄乎,拆开来!
  • 第二步:欸好像可以滚掉点空间!
  • 第三步:时间不够,斜率来凑

第一步

方差 S = 1 m ∑ i = 1 m ( x i − x ‾ ) 2 \texttt{方差}S=\frac{1}{m}\sum_{i=1}^m(x_i-\overline{x})^2 方差S=m1​i=1∑m​(xi​−x)2

可以将 n 2 n^2 n2移至左侧
m 2 S = m ( ∑ i = 1 m x i 2 ) − 2 ( ∑ i = 1 m x i ) 2 + ( ∑ i = 1 m x i ) 2 m^2S=m(\sum_{i=1}^{m}{x_i}^2)-2(\sum^{m}_{i=1}{x_i})^2+(\sum_{i=1}^{m}x_i)^2 m2S=m(i=1∑m​xi​2)−2(i=1∑m​xi​)2+(i=1∑m​xi​)2
m 2 S = m ( ∑ i = 1 m x i 2 ) − ( ∑ i = 1 m x i ) 2 m^2S=m(\sum_{i=1}^{m}{x_i}^2)-(\sum_{i=1}^{m}x_i)^2 m2S=m(i=1∑m​xi​2)−(i=1∑m​xi​)2

这就是我们要输出的东西

可以发现,第二项其实是个常数, m m m也可以最后乘

这样,需要维护的东西成了平方和

记 s i = ∑ j = 1 i x j s_i=\sum_{j=1}^{i}x_j si​=∑j=1i​xj​

d p dp dp式子就是 d p i , l = min ⁡ { d p j , l − 1 + ( s i − s j ) 2 } ( i < j ) dp_{i,l}=\min\{dp_{j,l-1}+(s_i-s_j)^2\}(i<j) dpi,l​=min{dpj,l−1​+(si​−sj​)2}(i<j)

第二步(此步可省略)

可以发现,我们能够不按常理出牌,先枚举 l l l,这样可以滚掉 l l l这一层,但要倒序枚举

伪代码:

for i=1->m:for j=n->1:for k=1->j-1:dp[j]=minimum(dp[j],dp[k]+(s[j]-s[k])^2)

第三步

重中之重到了!!!

我们还要继续拆式子(悲)

( s i − s j ) 2 = ( s j 2 − 2 s j s i ) + s i 2 (s_i-s_j)^2=(s_j^2-2s_js_i)+s_i^2 (si​−sj​)2=(sj2​−2sj​si​)+si2​

带进 d p dp dp式子内,得
d p i = min ⁡ { d p j + s j 2 − 2 s j s i + s i 2 } dp_i=\min\{dp_j+s_j^2-2s_js_i+s_i^2\} dpi​=min{dpj​+sj2​−2sj​si​+si2​}

斜率优化有个套路,就是先提再构

即提出常数项
d p i = min ⁡ { d p j + s j 2 − 2 s j s i } + s i 2 dp_i=\min\{dp_j+s_j^2-2s_js_i\}+s_i^2 dpi​=min{dpj​+sj2​−2sj​si​}+si2​

构造一个只与 j j j有关的函数
f ( j ) = d p j + s j 2 f(j)=dp_j+s_j^2 f(j)=dpj​+sj2​
d p i = min ⁡ { f ( j ) − 2 s j s i } + s i 2 dp_i=\min\{f(j)-2s_js_i\}+s_i^2 dpi​=min{f(j)−2sj​si​}+si2​

接着是斜率的老套路

一个 j 1 j_1 j1​比 j 2 j_2 j2​优且 j 2 < j 1 j_2<j_1 j2​<j1​,仅当
f ( j 1 ) − 2 s j 1 s i > f ( j 2 ) − 2 s j 2 s i f(j_1)-2s_{j_1}s_i>f(j_2)-2s_{j_2}s_i f(j1​)−2sj1​​si​>f(j2​)−2sj2​​si​
f ( j 1 ) − f ( j 2 ) > 2 s i ( j 1 − j 2 ) f(j_1)-f(j_2)>2s_i(j_1-j_2) f(j1​)−f(j2​)>2si​(j1​−j2​)
f ( j 1 ) − f ( j 2 ) 2 ( j 1 − j 2 ) < s i \frac{f(j_1)-f(j_2)}{2(j_1-j_2)}<s_i 2(j1​−j2​)f(j1​)−f(j2​)​<si​

这样与第一题截然相反,是要维护一个下凸包

但二分还是一样的

理论复杂度 O ( n log ⁡ n ) O(n\log n) O(nlogn)


与官方博文或参考文献对照,可更好理解

参考文献:https://www.luogu.com.cn/blog/aben-blog/xie-shuai-you-hua-dp

最新消息!最近发起活动,请选出其中最小的图片,有奖竞猜!(其实就是把名字写上去)

学习笔记——斜率优化dp相关推荐

  1. APIO2010 特别行动队 斜率优化DP算法笔记

    做完此题之后 自己应该算是真正理解了斜率优化DP 根据状态转移方程$f[i]=max(f[j]+ax^2+bx+c),x=sum[i]-sum[j]$ 可以变形为 $f[i]=max((a*sum[j ...

  2. HDU-3507Print Article 斜率优化DP

    学习:https://blog.csdn.net/bill_yang_2016/article/details/54667902 HDU-3507 题意:有若干个单词,每个单词有一个费用,连续的单词组 ...

  3. 【总结】斜率优化DP

    于是,XSC062开始写总结. 斜率优化DP 前置芝士 单调队列优化DP(夹带私货) 正文 我们以一道题为例. 打印文章 双倍经验 三倍经验 Solution 明显DP. 那么DP式就是: f i = ...

  4. NOI2007 货币兑换 - CDQ分治斜率优化dp

    斜率优化dp维护一个凸壳.如果\(x, y\)坐标都递增,可以用单调队列,如果只有\(x\)递增,可以在凸壳上二分斜率,如果\(x, y\)都不递增,则需要在凸包中插入,可以用平衡树或cdq分治维护. ...

  5. CF-311B Cats Transport(斜率优化DP)

    题目链接 题目描述 小S是农场主,他养了 \(M\)只猫,雇了 \(P\) 位饲养员. 农场中有一条笔直的路,路边有 \(N\) 座山,从 \(1\) 到 \(N\)编号. 第 \(i\) 座山与第 ...

  6. 【洛谷3648】[APIO2014] 序列分割(斜率优化DP)

    点此看题面 大致题意: 你可以对一个序列进行\(k\)次分割,每次得分为两个块元素和的乘积,求总得分的最大值. 区间\(DPor\)斜率优化\(DP\) 这题目第一眼看上去感觉很明显是区间\(DP\) ...

  7. 深度学习笔记:优化方法总结(BGD,SGD,Momentum,AdaGrad,RMSProp,Adam)

    深度学习笔记(一):logistic分类  深度学习笔记(二):简单神经网络,后向传播算法及实现  深度学习笔记(三):激活函数和损失函数  深度学习笔记:优化方法总结  深度学习笔记(四):循环神经 ...

  8. HDU 3507 Print Article(斜率优化DP)

    题目链接 题意 : 一篇文章有n个单词,如果每行打印k个单词,那这行的花费是,问你怎么安排能够得到最小花费,输出最小花费. 思路 : 一开始想的简单了以为是背包,后来才知道是斜率优化DP,然后看了网上 ...

  9. HDU 2993 MAX Average Problem(斜率优化DP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2993 题目大意:给定一个长度为n(最长为10^5)的正整数序列,求出连续的最短为k的子序列平均值的最大 ...

最新文章

  1. 使用MASM04 - Win32汇编语言012
  2. android查询竞价处理,公平可靠的竞价方式,应对越来越高的流量获取成本,如何解决推广费用过高的问题可能是...
  3. 函 float *search(float(*pointer)[4],int n)
  4. 计算机视觉与深度学习 | ORB特征匹配:基于OpenCV+Python(暴力匹配、FLANN)
  5. 程序人生:提高代码运行效率的9个技巧
  6. discuz x2.5用户注册后邮箱认证后无法收到邮件或者直接进垃圾箱
  7. 记一次Task抛异常,调用线程处理而引发的一些随想
  8. 中科院自动化所与华为联合提出!视觉目标检测大模型GAIA
  9. arcgis不闭合线转面_地理工具学习--arcgis篇(15):CAD和SHP的简单转换
  10. fastjson转换包含date类型属性的对象时报错com.alibaba.fastjson.JSONException: For input string 解决方法
  11. 你们是不是很缺大数据工程师?
  12. 六石编程学:方便调试输出的标准C代码
  13. 【AI PC端算法优化】七,RGB和YUV图像颜色空间互转SSE优化
  14. html中的js代码测试,w3school JS测验
  15. 1357. 路径总和 II
  16. 华为云HMS Core 助力鸿蒙开发
  17. win10新建计算机账户,Windows10系统创建microsoft帐户的方法
  18. 企业微信如何快速高效添加好友?
  19. 计算机英语测试,计算机专业英语测试
  20. PCB与设备外壳接地问题

热门文章

  1. 经典算法和OJ网站(开发者必备)
  2. 高等数学学习笔记——第七十八讲——极坐标下二重积分的计算
  3. Python Behave框架的入门使用
  4. CNN-Attention
  5. mysql语句boll线_能把“BOLL指标”说透的只有这篇!教你寻找最佳买卖
  6. SQL默认时间datetime类型转换为年月日格式
  7. 立创开源zigbee2mqtt网关 简称:z2m
  8. 和荆老师,几个好兄弟去K歌
  9. 迅雷快鸟重大升级,23省市电信光纤宽带可提速至200M
  10. FFmpeg视频的旋转rotate