题解:P11475 [COCI 2024/2025 #3] 红蓝牌 / Karte
解析
规模很小,考虑枚举选择了哪些蓝牌。
假设选择了集合 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;
}