- E - Popcount Sum 3
【思路分析】数位 DP(Digit DP)+ Popcount 限制
- 2025-5-22 19:54:11 @
【思路分析】
数位 DP(Digit DP)+ Popcount 限制
问题本质:
我们需要枚举 x 的所有可能值中,二进制中恰好有 K 个 1 的数的和。 直接枚举会超时,因为 N 最多可达 级别。因此我们使用 数位动态规划(Digit DP) 的思想。
📐 状态设计
用 和 表示: • :表示从第 位开始,已经选了 个 1,当前是否处于 “紧贴 的前缀”() 的情况下,有多少种合法数字组合。 • :在上述状态下,这些合法数字组合的数字之和。
💡 状态转移过程说明(从高位向低位转移):
• 假设当前处理的是第 位(从高位向低位),可以选择这一位为 或 ; • 要维持不超过 ,所以需要一个 标志; • 如果 的第位是,可以选择当前位为0(从1→0),或者保持为1; • 如果 的第 位是 0,只能选 0, 继续维持为 1; • 每次选 1 时, 也需要加 1,并且加上当前位代表的数值 到 中。
示例(简化说明)
假设 ,,我们想找所有 的数中,二进制中正好有 2 个 1 的所有数的和。 合法数有: 这些数的和是:
f[61][0][1] = 1;
初始状态:从最高位 60 开始,选了 0 个 1,处于 状态。
for (int i = 60; i >= 0; i--) {
int d = (1ll << i), dm = d % Mod;
从高位往低位遍历, d是当前位的值,后续加和要乘以该值。
if (n & d) { ... } else { ... }
根据 n 当前位是 1 还是 0,确定 转移方式。 每次转移: • 更新 f 计数(有多少种方案); • 更新 g 和值(这些方案的总和); • 注意 加法。
0 comments
No comments so far...
Information
- ID
- 66
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- 6
- Tags
- # Submissions
- 1
- Accepted
- 1
- Uploaded By