1 条题解
-
0
这是一个关于在特定规则下最大化议会通过议案数量的策略问题。
核心要素 描述 问题目标 对每个议员 作为议长时,通过选择合适的副议长,最大化通过的议案数。 关键观察 只有那些初始赞成票数 等于 或 的议案 ,其通过与否会受到移除议长和副议长投票的影响。 核心策略 对于议长 ,找出那些 的"关键议案"集合 。最优副议长 需要对这些关键议案投尽可能多的反对票(即 )。 推荐算法 位运算预处理与高维前缀和(SOS DP),复杂度约为 O(M · 2^M + N · M)。 特殊情形 若议长 的关键议案集合 为空,则所有议案都能通过,答案为 。 🔢 问题分析
议会通过的议案需要满足:除了议长和副议长,投赞成票的议员数 不少于 。
设 为对议案 投赞成票的总人数。当议长为 ,副议长为 时,议案 通过的条件是:
$$cnt[j] - A_{i,j} - A_{k,j} \geq \lfloor N/2 \rfloor $$其中 表示议员 对议案 的投票(1赞成,0反对)。
💡 关键步骤与解法
-
预处理:
- 计算每个议案 的初始赞成票数 。
- 将每个议员 的投票模式编码为一个位掩码 ,其中第 位为 。
-
确定关键议案:
- 对于议长 ,找出所有满足 的议案 ,构成集合 。这些议案必须由副议长投反对票才能通过。
-
寻找最优副议长:
- 我们需要找到一个副议长 (),其投票模式 在关键议案集合 对应的位上为 的数量尽可能多。这等价于 是 的补集的子集。
- 为了快速查询,我们可以使用高维前缀和(SOS DP) 来预处理每个掩码对应的最大 popcount(或议员数量)。
-
计算答案:
- 对于议长 ,设其关键议案集合 对应的位掩码为 。
- 通过查询预处理好的数据结构,找到所有议员中(除 自己),其投票模式 是 补集的子集时, 与 补集的最大交集大小(即投反对票的关键议案数)。
- 通过的议案数 = 。
🧩 算法步骤
- 计算 数组:遍历所有议员,统计每个议案的赞成票数。
- 构建位掩码:为每个议员 计算 。
- 预处理高维前缀和:
- 初始化数组 ,其大小为 。对于每个掩码 ,如果有议员 满足 ,则 存储 或进行数量统计。
- 进行 SOS DP 计算:对每一位 ,更新 (具体更新方式取决于我们想查询的是最大 popcount 还是存在性)。
- 处理每个议长:
- 对于议员 ,计算 ,其中 是关键议案集合。
- 如果 ,则答案 。
- 否则,查询 (在 位范围内)的子集中所有可能的 的最大 popcount 值 。则 。
💎 总结
该问题的核心在于将寻找最优副议长的问题转化为在状态压缩空间下的子集查询问题,并利用高维前缀和(SOS DP) 进行优化。由于 ,状态压缩是可行的。
-
- 1
信息
- ID
- 5526
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者