动态规划优化方法

之前我们学习过动态规划方法,但是并没有对DP进行系统细致的优化。今天来看一下DP的优化方法。

  • 一、矩阵优化
    线性代数教材中可能讲过,通过矩阵进行快速的重复运算(矩阵快速幂)。
    (以下是矩阵快速幂的写法)
    矩阵快速幂
    直接看题:
    求斐波那契数列第n项余1e9+7后的值,其中1<=n<263
    通过使用普通的动态规划(递推)显然会爆掉,矩阵加速就十分使用与这种线性的递推DP,构造矩阵再配上矩阵的快速幂,以logn的时间复杂度求出答案。
    答案解释

  • 02 单调队列优化
    多重背包的时候就可以用到,主要突出的是单调性。
    讲解视频
    例题:n个数的序列,求每一项前m个数的最小值,不足m项从第一项开始,1<=m<n<=1e5
    可以维护一个双端队列,队列中记录序列位置,队列中的数字在序列中对应位置的值大小单调递增。每次处理完一个数将其与队列尾部比较,如果比队列尾部小或相等则弹出尾部,一直到队列为空或队列尾部比当前这个值小,将这个位置插入队列尾部。计算当前位置的答案时先将位置太小的首部弹出,然后取队列首部的位置即可。
    时间复杂度O(n)。

  • 03 线段树优化
    具体可以见我之前写过的线段树这篇文章

  • 04 斜率优化
    当状态转移方程:方程
    𝜔(i, j)包含与i有关的项和与j有关的项的乘积如下,且已知a[i]和b[i]单调递增,该如何处理?

做变换:
变换
等式就可以看作一条直线,每个j都确定出一个点(x, y),对于当前要求解的i,其斜率已确定(且随i单增),要使dp[i]最大即要使这条直线过某一个j形成的点并使得的截距最小。
变换
斜率优化
斜率优化
假设之前已处理完前9个点,将他们画在坐标平面上,可以发现,不论当前点a[i](斜率)是多少,能使截距最小的点一定选在标出来的四个点形成的下凸包中。且当𝑘_𝑗1𝑗2≤𝑘≤𝑘_𝑗2𝑗3时,选择j2点最优。
可以用双端队列来维护这个下凸包,当前双端队列中按顺序存放有j1~j4四个点。
判断当前计算的i的斜率是否大于𝑘_𝑗1𝑗2(队列中前两个点的斜率),若大于,则把队首弹出,因为i的斜率会越来越大,队首之后肯定也不会是最优转移点,弹出后继续判断。然后取队首作为转移点,此时直线的截距一定最小。
设刚计算完的点为j5。
判断𝑘_𝑗3𝑗4(即队列末尾两个点形成的斜率)是否大于𝑘_𝑗3𝑗5(j5与队列末尾倒数第二个点的斜率),若大于则将队尾弹出,因为加入j5后原队尾已经不在下凸包上,之后肯定不会作为最优转移点,弹出后继续判断。
将j5插入到队列的尾部。
核心算法
建议使用手写的双端队列,因为会访问到首部第二个元素和尾部第二个元素,用stl里的deque会麻烦一点

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值