DP 学习笔记(四):高级 DP 类型、高级 DP 优化

DP 新类型

子集和DP (SOS DP)

有点像是只有 01 的数位 DP

子集和 DP 一般用来求解某类特殊的高维前缀和问题,这类问题在每个维度上只有 0/1,且每个点有点权。

举个例子:给定一个含 2n 个整数的集合 A,对于任意一个集合 SA,我们需要求 S 中所有元素的 Ai 和,即 Fi=iSAi

考虑普通的状压 DP 或枚举子集的想法,复杂度分别为 O(4n)O(3n),都太高了。其实,可以发现如果一个状态的二进制位上有 k0,那么这个状态将会被遍历到 2k1 次,考虑能否用 DP 的方法优化。

这次我们一位一位地 DP,记 F(S,i) 表示考虑 S 的所有子集,其中前 i 位与 S 一样,后面每位上可以与 S 不同的子集构成的集合,比如 F(1011010,3)={1011010,1011000,1010010,1010000},现在,如果 S 的第 i 位是 0,那么它的子集的第 i 位一定是 0,于是 F(S,i)=F(S,i1)

如果 Si 位上是 1,那么它的子集这一位上可能是 1,也可能是 0,如果子集这一位上是 1,那么 F(S,i) 依然 =F(S,i1),如果这一位上是 0,那么它可以简化为 Sxor2i 的第一类的子集,于是 F(S,i)=F(Sxor2i,i1),那么 DP 的顺序就被定了下来:

于是,设 fi,j 表示当前集合为 j,前 i 位必须与 j 相同的子集的权值和,于是 DP 方程可以写成 fi,j={fi1,jji0fi1,j+fi1,jxor2iji1

可以发现 fi 只与 fi1 有关,于是可以滚动数组优化,考虑到 jxor2i<j,于是内层循环需要倒序枚举。

完整代码:其实很短

for(int i = 0; i < (1 << n); i++)
    f[i] = a[i];
for(int j = 0; j < n; j++)
    for(int i = 0; i < (1 << n); i++)
        if(((i >> j) & 1) == 0)
            f[i | (1 << j)] += f[i];

复杂度为 O(n2n)

例题一

例题二

自动机DP

整体DP

动态DP

先从最基础的 DP,也就是递推讲起。

首先,递推分为线性递推和非线性递推,非线性递推比如 Somos-4 序列(1,1,1,1,2,3,7,23,59,),它的递推式是 fi={1i{0,1,2,3}fn1fn3+fn22fn4i4,其中出现了 2 次项与 1 次项,因此不是线性的,在这里不做讨论。

常见的线性 DP 又分为以下 3 种:

  • 常系数线性递推。通常可以写成:fn=i=1kcifni,其中 ci 是常数。比如几何级数:1,q,q2,q3,,或者斐波那契数列:fi={1i{1,2}fi1+fi2i3

  • 普通整式递推。通常可以写成:fn=i=1kci(n)fni,其中 ci(n) 是关于 n 的函数。比如阶乘序列:1,2,6,24,,或者莫茨金序列:fi={1i{0,1}2n+1n+2fi1+3n3n+2fi2i2

  • q,qn 双参的整式递推。通常可以写成::fn=i=1kci(q,qn)fni,其中 ci(q,qn) 是关于 qqn 的函数。比如 q 阶乘序列:[n]q!=(1+q)(1+q++qn1)

在这里,我们只解决常系数线性递推,而常系数线性递推又分为常系数齐次线性递推和常系数非齐次线性地推。动态 DP 一般解决常系数齐次线性递推问题在小数据范围内的求解(可见这只是冰上一角,但这一角也能把你压垮)。

考虑到 fi 的值只与 fi1fik 相关,那么我们可以考虑将 fi1fik 从上到下排列形成一个向量 [fi1fi2fik],这时,如果找到一个矩阵 A,使得 A[fi1fi2fik]=[fifi1fik+1],那么我们就可以通过不断乘以 A 的形式来表示递推。事实上,这个矩阵 A 就是[c1c2c3ck1ck10000010000010000010],现在,我们就可以用快速幂优化不断乘以 A 的操作,做到 O(log2nk3)k 为矩阵边长)。

DP优化

Slope Trick

WQS 二分

FFT

参考资料

posted @   JPGOJCZX  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
点击右上角即可分享
微信分享提示