• dp的优化总结


    前缀和优化

    解决问题 如果dp转移过程中需要反复的使用一个求和式时,可以将数列的前缀和先预处理出来。运算一般要满足可减性。

    题目

    单调队列优化

    前置技能 单调队列(经典问题模型:P1886 滑动窗口题解

    解决问题 优化形如 (f_i = min/max{ g_j | l_i le j le i - 1 } + w_i) ,且满足 (l_i le l_{i+1}) 的转移。

    解释 对于序列中的每个点,从其左侧一段决策区间内的最值进行转移,且决策区间随着序列下标的增大也不断右移,类似于窗口向右滑动。

    解法 设 (j<k) ,容易发现如果 (g_j) 劣于 (g_k) 的话,那么当决策区间移动到 (k) 以后, (j) 永远不会成为最优决策点,再也不会被转移使用了。所以,我们要维护一个队列,满足下标递增决策性递减。我们需要当前的队首成为最优决策点,那么当队首第一次超出了区间范围(以后也就永远超出了)就把它出队。为了保证单调性,队尾新加入点之前,要先把队列中比它劣的点依次从队尾出队。

    题目

    决策单调性

    解决问题 发现决策之间的递变规律。

    • 优化形如 (f_i = min/max w_{i,j}) 且对于每个 (i) 和它的最优决策点 (j) 都有单调性的转移方程。这类问题一般对题目的性质要求较高,因为 (j) 是独立的。只需要维护指针,按照单调性不断寻找最优答案即可。类似于尺取法。
    • 形如(f_i = min/max{ g_j | 1 le j le i - 1 } + w_{i,j}),且 (f_i) 的最优决策点为 (p_i) ,也就是 (f_i)(g_{p_i} + w_{i,p_i}) 处转移最优。若满足 (p_i le p_{i + 1}) ,则该方程满足决策单调性。因为 (j) 不独立了,所以我们只能把有用的决策先存起来。使用如下策略。

    策略1:二分栈

    使用决策二分栈,一种单调栈来维护所有有用的决策。

    二分栈 我们将 (g_j + w_{i,j}) 视为关于 (j) 的函数。因为决策单调,所以对于栈中的任意相邻两个决策点,我们都可以通过二分找到一个临界值 (k) ,使得序列中在 (k) 之前的时候,其中一个作为决策转移到 (f_k) 更优,而 (k) 以后另一个更优。

    栈顶为当前的最优解。而如果栈中有不止一个元素,则可能存在一个 (i) ,使得到 (i) 之后栈里面的决策比栈顶优了,这时就需要弹栈。对于当前的 (i) ,如果当前栈顶下面与栈顶相邻的决策在 (i) 之前就比栈顶更优了,就要把栈顶弹掉。

    策略2:分治

    二分栈存在局限性,那就是必须能快速计算 (w_{i,j}) 。如果不能 (O(1)) 计算的话,在求临界值 (k) 的时候复杂度会严重退化。

    由于转移过程是单调并且离线的,我们考虑分治。假设当前我们求解一段区间 (f_{l,r}) ,而所有 (f_{l,r}) 的最优决策点在 ([L,R]) 之间。对于 ([l,r]) 的中点 (mid) ,我们可以暴力扫一遍 (L−mid) ,找到它的最优决策点 (k)。因为决策单调,所以 (f_{l,mid−1}) 的决策落在 ([L,k]) 上,而 (f_{mid+1,r}) 的决策落在 ([k,R]) 上,变成了两个规模减半的小问题。时间复杂度为 (O(nlog n))

    斜率优化

    形如 (f_i = min/max{ g_j | 1 le j le i - 1 } + w_{i,j}) 的转移方程式。

    考虑决策 (j_1)(j_2) ,如果 (j_1)(j_2) 优,那么 (g_{j_1} + w_{i, j_1} le g_{j_2} + w_{i, j_2})
    根据题目将 (w) 展开,如果可以化为 (frac{y_{j_1}-y_{j_2}}{x_{j_1}-x_{j_2}} le k_i) 的形式,那么我们把每个决策点看成 ((x_j,y_j)) 分布在坐标系上,真正使用到的决策点形成的一个凸壳。

    如果 (x) 单调,可以用单调栈维护凸壳,转移时使用当前直线的斜率(线性规划),在栈内二分最优解。
    如果斜率 (k) 单调,那么用单调队列维护凸壳,队首为当前最优决策。转移之前如果队首不优就出队。

  • 相关阅读:
    东汉末年,他们把「服务雪崩」玩到了极致(干货)
    我是一个秒杀请求,正在逃离这颗星球...
    《SpringCloud实战项目》系列目录
    《Java并发必知必会》系列
    微前端大赏二-singlespa实践
    redis传输协议规范(翻译)-上(Redis Protocol specification)
    oracle 查询数据库锁及锁处理
    golang string 转 int && int 转 string
    Json刚明白,怎么又出来个Bson?
    Linux中的buffer和cache到底是什么?今天终于明白了
  • 原文地址:https://www.cnblogs.com/solvit/p/11331924.html
Copyright © 2020-2023  润新知