1 条题解
-
0
自动搬运
来自洛谷,原作者为

一扶苏一
休息结束。邮箱 yifusuyi@qq.com搬运于
2025-08-24 23:07:41,当前版本为作者最后更新于2024-12-28 00:09:07,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
解析
规模很小,考虑枚举选择了哪些蓝牌。
假设选择了集合 里的蓝牌,我们可以知道选择每张红牌贡献的好对数。具体来说,如果第 张红牌能和集合 里的蓝牌产生好对,那么第 张牌贡献的好对数就是 。因为牌的数量很少,所以 和 都可以压位成
int,集合求交可以对两个整形做按位与,求集合大小可以通过std::popcount来实现。注意这里 是蓝牌选牌集合, 是第 张牌的贡献,两者含义不是对称的。
接下来考虑枚举选了几张红牌。显然尽可能选择贡献较大的红牌是优的,所以把 数组从大到小排序,贪心地选前几项并尝试更新答案即可。
时间复杂度 ,其中 表示一次
popcount的时间。代码
#include <bits/stdc++.h> int main() { int n, m, x, y; std::cin >> n >> m >> x >> y; std::vector<int> matched(n); for (auto &i : matched) { std::string s; std::cin >> s; for (int j = 0; j < m; ++j) if (s[j] == '1') i ^= 1 << j; } int ans = 0; for (int lhs = 0, upc = 1 << m; lhs < upc; ++lhs) { std::vector<int> rhs(n); for (int i = 0; i < n; ++i) { rhs[i] = std::popcount(static_cast<unsigned>(matched[i] & lhs)); } std::sort(rhs.begin(), rhs.end(), std::greater<int>()); int matchedCnt = 0; int lhsCnt = std::popcount(static_cast<unsigned>(lhs)); for (int j = 0; j < n; ++j) { matchedCnt += rhs[j]; ans = std::max(ans, matchedCnt - y * lhsCnt - x * (j + 1)); } } std::cout << ans << std::endl; }
- 1
信息
- ID
- 11220
- 时间
- 1000ms
- 内存
- 500MiB
- 难度
- 3
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者