Skip to content

背包与背包型DP

定义

  • 狭义的背包问题是常见的选物品。
  • 广义的背包问题指一种特殊DP状态设计:
    • DP状态的一维表示选择的量。
    • 题目对该量有限制。例如,常见的量有:
      • 已选物品的个数。
      • 已进行操作的代价。

常见背包类型

  • 01背包
  • 完全背包
  • 多重背包
  • 树上背包

常见处理方法

通用技巧

  1. 一些剪枝
    • 将一定不选的物品直接去掉(价值关于体积必须递增)。即若对于物品 iijjii 的体积 viv_i 小于 jj 的体积 vjv_j),且 wiviwjvj\frac{w_i}{v_i} \leq \frac{w_j}{v_j}ww 表示价值),则物品 ii 可直接去掉。
    • 将DP状态设成“恰好”,用 vector 存状态,将不优的状态去掉(dp值关于体积必须递增)。绝大多数题目出题人都不会卡(卡不掉)这个做法,可以放心使用。
    • 将体积相同的物品合并处理,可能是直接删掉,或是排序处理(因为转移只与体积有关)。
  2. 二进制分组
    • 可将物品数量降为 log\log 个。
    • 用于处理多重背包或完全背包。
  3. 折半搜索:处理 nn304030 - 40 左右的问题。
  4. 合并和插入的转化(优化状态或转移)
    • 插入转合并(较常用)
      • 条件:合并复杂度更优。
      • 处理:结合分治/倍增实现。
      • 例子
        • 倍增FFT。
        • 分治 + 闵可夫斯基和。
    • 合并转插入
      • 条件
        • 插入复杂度更优。
        • 需特别注意插入顺序的影响。
      • 处理:可能结合启发式实现。
      • 例子:树上连通块DP的启发式做法。
  5. 性价比背包
    • 将物品按价值与体积的比 wv\frac{w}{v} 排序后选择。
    • 可保证总体积为某个前缀和时,其价值和最优。
  6. 处理存在性背包
    • 存在性完全背包(同余最短路)
      • 实现:转圈实现。
      • 复杂度:最小的物品体积 vminv_{min} * 体积种数 mm,即 O(vminm)O(v_{min} \cdot m)
    • 存在性多重背包(bitset)
      • 复杂度:本质不同的转移数 tt * 背包容量 VV,即 O(tV)O(t \cdot V)
    • 进制分解的结论(特殊存在性01背包)
      • 物品按体积 vv 从小到大排序后,满足 vij=1i1vj1v_i \leq \sum_{j = 1}^{i - 1} v_j - 1
      • 那么在上下界之间的任何一个容量 CC,都能通过类似进制分解的方法构造出解。
      • 例题:ARC LIS on tree 2。
  7. 处理计数背包
    • 背包合并:利用多项式卷积FFT/NTT,即通过计算两个多项式的卷积来合并背包。设两个背包对应的多项式为 A(x)=i=0naixiA(x) = \sum_{i = 0}^{n} a_i x^iB(x)=j=0mbjxjB(x) = \sum_{j = 0}^{m} b_j x^j,则它们的卷积 C(x)=A(x)B(x)=k=0n+m(i+j=kaibj)xkC(x) = A(x) \cdot B(x) = \sum_{k = 0}^{n + m} (\sum_{i + j = k} a_i b_j) x^k
    • 可删除背包(回退背包)
      • 适用范围:类似高维前缀和/01背包方案数那样的数值DP转移(最优化不行)。
      • 经典例题
        • 消失之物:带回退的01背包。
        • solution:略。
        • 题目:给定数组 a[1n]a[1 \sim n],每次询问给定 l,rl, r,问 a[lr]a[l \sim r] 中选 kk 个数的乘积期望是多少。两个方案不同当且仅当 kk 个数的下标组成的集合不同,n,q1000n, q \leq 1000
        • solution:莫队加上回退背包即可。
  8. 处理最优化背包
    • 体积小的多重背包处理(普通增函数和凸包合并)
      • 按体积分组后,同一体积内为 1D/1D1D/1D 问题。
      • 按总体积对当前体积的余数,转移可分成若干类,每类互不干扰。
      • 观察价值函数,有明显凸性,可猜测具有决策单调性。注意,DP数组本身无凸性。
      • 例题:Jewel Thief。
    • 带凸性的背包合并(凸包合并):利用闵可夫斯基和。对于两个凸多边形 PPQQ,它们的闵可夫斯基和 P+Q={p+q:pP,qQ}P + Q = \{p + q : p \in P, q \in Q\}
    • 带凸性的背包求恰 kk 个物品:使用wqs二分。
    • 体积小的多重背包问题通法(复杂度与背包容量无关)
      • 贪心 + 小范围dp
        • 适用范围:任意背包,mm(物品数量),viv_i(物品体积),wiw_i(物品价值)可负。
        • 具体做法
          • 先将体积为负的物品默认选上,然后将其体积和价值取反,使所有体积变为正。
          • 先用性价比背包尽量接近限制容量 CC
          • 之后需删一些已选物品并添加一些未选物品,用多重背包实现,背包容量为 w2w^2,其中 ww 是最大的体积。
        • 对背包容量的证明
          • 首先,尽量接近后的体积与限制容量的差 $ \lt w$。
          • 最终的背包体积与限制容量的差也 $ \lt w$。
          • 中间调整过程存在一种方案,使当前体积与限制容量的差始终 $ \lt w$。
          • 由于性价比背包的最优性,任何一种总体积在调整过程中最多被遍历一次(否则调整后会更优)。
          • 所以最多选 ww 个物品增加体积,ww 个物品减少体积,背包容量为 w2w^2
        • 例题:Uplifting Excursion。
    • 体积小但容量较大的完全背包处理:(不是通解,对容量下界有限制)
      • P9140 [THUPC 2023 初赛] 背包
      • 通解:与普通完全背包结合,可实现总复杂度 O(nmaxv2)O(n \cdot \max v^2)

可能用到的结论

  1. 总体积一定时,不同的体积数是根号级别的
    • proof:利用根号分治可证。
    • 这表明,有容量限制(和限制)时通常满足根号分治的前提条件,难点在于设计算法。
  2. 物品体积正负都有,总体积恰好是 sumsum,绝对值最大的物品体积为 maxvmaxv
    • 存在一种调整物品放置顺序的方法,使任何时候的体积都在 [l,r][l, r] 中,其中 l,rl, r 满足 rl+12maxvr - l + 1 \geq 2 \cdot maxv,且 00sumsum 均在 [l,r][l, r] 中 。
    • proof:对于当前体积 nwnw,若下一个体积使 nwnw 越过范围,不妨设 nwmaxv<lnw - maxv \lt l(超过下界 ll),此时必然存在一个正体积的物品,使用该物品可使 nwnw+maxvrnw \to nw + maxv \leq r
    • 需注意,这不能直接通过朴素的背包DP实现,因为要求特定顺序。
  3. 物品体积有正负,物品价值均为正时,最优解不会重复经过同一个总体积
    • 特别地,若是多重背包,可将负价值物品先钦定必选从而转成正价值。
    • proof:显然。
    • 注意,同余最短路、最优化多重背包的做法都用到了这个结论的变体。
  4. 物品体积有正负,最终体积和为恰 00 的01背包
    • 过程中可取背包最大容量为 [maxvmaxv,maxvmaxv][-maxv \cdot \sqrt{maxv}, maxv \cdot \sqrt{maxv}]

Released under the MIT License.