背包,子集和以及 (max, +) 卷积在特殊情形下的求法
子集和 1:总重量不太大
有 n 个物品,每个物品重量为 wi,且 ∑iwi=C。你需要对于 k∈[1,C] 均求出是否存在子集和 =k。
时间复杂度 O(C√Cω),空间复杂度 O(n+Cω)。
我们对于相同重量的物品二进制分组,然后暴力 01 背包,用 bitset 加速即可。
时间复杂度证明:
不妨设重量为 w 的物品有 a 个,则 m∑i=1wiai=C。二进制拆分后的物品数为 ∑k=0m∑i=1[ai≥2k]。
对于固定的 k,满足 [ai≥2k] 的 i 有 √C2k 个,因此物品数 ∑k√C2k=√C∑k2−k/2≤√2√2−1√C。
子集和 2:单个重量不太大
有 n 个物品,每个物品重量为 wi,满足 wi≤D。问是否存在子集和 =C。
时间复杂度 O(nD),空间复杂度 O(n+D) 或 时间复杂度 O(n√nDω),空间复杂度 O(n+√nDω)。
法一:
先找到最大的 k 满足 k∑i=1wi≤C,问题转化为能否从 {−w1,⋯,−wk,wk+1,⋯,wn} 选出子集和 C−k∑i=1wi。该做法的核心思想是:如果当前子集和 >C,那么从 w1∼wk 中选一些数减到 ≤C,否则从 wk+1∼wn 中选一些数加到 >C。
我们定义 can(tot,l,r) 表示是否存在 λl,λl+1,⋯,λr={0,1} 满足 l−1∑i=1wi+r∑i=lλiwi=tot。
性质 1:固定 tot,r,则 can(tot,l,r)=1 的 l 为一段前缀。
我们定义 dptot,r 表示最大的 l 满足 can(tot,l,r)=1(如不存在,dp=−1)。考虑转移。
性质 2:固定 tot,l,则 can(tot,l,r)=1 的 r 为一段后缀。
据此有 dptot,r≤dptot,r+1,于是有三类转移:
- dptot+wr+1,r+1←dptot,r
- dptot,r+1←dptot,r
- dptot−wl′,r←l′ (l′∈[1,dptot,r))
我们发现第三类转移有 O(n) 条,但是对于固定的 tot,我们在 dptot,r 时有意义的转移只有 l′∈[dptot,r−1,dptot,r),否则可以在 dptot,r−1 的时候就转移掉。
因此,对于固定的 tot,第三类转移总共有 O(n) 条,因此时间复杂度是均摊 O(nD) 的。
法二:
考虑随机打乱这个集合,则过程中期望达到的最值为 O(√nD),用 bitset 加速即可。
(max, +) 卷积
给定两个长为 n 的序列 A,B,求它们的 (max,+) 卷积 C。保证 B 是凸函数。
时间复杂度 O(nlogn) 或 O(n),空间复杂度 O(n)。
法一:
我们记 Ci 的决策位置(即 B 序列位置)为 fi,容易证明 fi−1≤fi。因此直接分治即可。
时间复杂度 O(nlogn),空间复杂度 O(n)。
法二:
考虑构建一个 (2n−1)×n 的矩阵 X,满足 Xi,j=Ai+Bi−j。我们想要的即为 X 的每行最小值。
由于 B 是凸的,所以 X 是完全单调矩阵,用 SMAWK 求解即可。
不过听 Froggy 说 SMAWK 的效率被二分栈 / 分治吊打,所以可能 not practical。
时间复杂度 O(n),空间复杂度 O(n)。
01 背包:单个重量不太大
有 n 个物品,每个物品重量为 wi,价值为 vi,不同的 wi 有 D 个。选出最大的子集 S 满足重量和不超过 C,且总价值最大。
时间复杂度 O(nlogn+DClogC) 或 O(nlogn+DC),空间复杂度 O(n+C)。
对于相同 w 的物品,我们肯定将 v 从大到小贪心取,图像为一个凸函数。因此我们将背包在模 C 意义下分别做 (max,+) 卷积即可。
完全背包:单个重量不太大
有 n 个物品,每个物品重量为 wi,价值为 vi,满足 wi≤D。选出最大的可重子集 S 满足重量和不超过 C,且总价值最大。
时间复杂度 O(D2logC),空间复杂度 O(n+D)。
注意到对于 i>D,有 dpi=maxj+k=i(dpj+dpk),且如果 |j−k|>D,我们始终可以调整得到 |j−k|≤D。
因此通过 [dpj−D2,⋯,dpj+D2] 以及 [dpk−D2,⋯,dpk+D2],可以暴力卷积得到 dpj+k 的值。
现在,假如我们知道了 [dpk−D,⋯,dpk+D],它卷自己可以得到 [dp2k−D,⋯,dp2k+D]。因此采用倍增的形式可以快速计算出 [dpC−D,⋯,dpC],答案即为其中的最大值。
初始化的地方,暴力计算 [dp0,⋯,dp2D] 即可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!