1 条题解
-
0
题意简化
容量为 的背包,有 种物品:
- 第 种物品体积为
- 第 种物品最多可以用 个
求装满背包的方案数,模 。
。
核心思想:根号分治
1. 问题分析
这是多重背包问题,但 很大,直接 DP 会超时。
观察:物品体积从 到 ,但大体积物品数量少。
2. 根号分治
设 (约 316)。
将物品分为两类:
- 小物品:体积 (约316种)
- 大物品:体积 (约 种)
3. 分别处理
第一部分:大物品(体积 > m)
大物品最多用 个,数量少。
设 :用了 个大物品,体积和为 的方案数。
转移:
- 加一个体积最小的():
- 所有大物品体积+1(巧妙转化):
最终 表示用大物品凑出体积 的方案数。
第二部分:小物品(体积 ≤ m)
小物品体积小但数量多,用前缀和优化的多重背包。
设 :只考虑前 种小物品(体积1..i),凑出体积 的方案数。
转移(完全背包但有限制):
$$dp_2[i][j] = \sum_{k=0}^{\min(i, \lfloor j/i \rfloor)} dp_2[i-1][j-k\cdot i] $$用前缀和优化到 :
- 维护前缀和数组
- 注意每个物品最多用 个,所以减去 的部分
最终 表示用小物品凑出体积 的方案数。
4. 合并答案
背包总容量 ,可以:
- 用大物品凑 体积
- 用小物品凑 体积
方案数:
代码解析
变量说明
m = sqrt(n):分界点dp_1[][]:大物品 DPdp_2[][]:小物品 DPf[], g[]:最终方案数sum[]:前缀和优化
函数功能
solve_1():处理大物品solve_2():处理小物品(前缀和优化多重背包)
复杂度分析
- 大物品 DP:
- 小物品 DP:
- 总复杂度:,可过
关键优化
1. 根号分治
- 大物品:体积大,数量少,用特殊 DP
- 小物品:体积小,用优化的多重背包
2. 大物品的巧妙转化
将所有大物品体积同时+1的转移,减少状态数。
3. 前缀和优化
小物品多重背包用前缀和降到 转移。
样例解释
,物品:
- 体积1:最多1个
- 体积2:最多2个
- 体积3:最多3个
方案:
- 1+1+1
- 3
输出:2
代码特点
- 根号分治经典应用
- 大物品的特殊 DP 设计
- 小物品前缀和优化
- 模运算处理
- 1
信息
- ID
- 6018
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者