专栏文章

题解:P11475 [COCI 2024/2025 #3] 红蓝牌 / Karte

P11475题解参与者 3已保存评论 2

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
2 条
当前快照
1 份
快照标识符
@miq8bqj0
此快照首次捕获于
2025/12/04 00:36
3 个月前
此快照最后确认于
2025/12/04 00:36
3 个月前
查看原文
注意到数据范围很小,因此考虑暴力枚举选哪些红牌。
wiw_i 代表选了第 ii 张蓝牌的话,会有哪些红牌和他产生贡献。为了方便,可以转化成二进制数存储。显然这个东西可以预处理出来。
设当前选的红牌集合为 ii(也是一个二进制数),可以枚举所有蓝牌。对于第 jj 张蓝牌,如果该蓝牌的贡献 iwji \cap w_j(实现时可以使用按位与运算)比 yy 大,那么表示选第 jj 张蓝牌是赚的。将其贡献累加到计数器上,最后减去 x×popcount(i)x \times \operatorname{popcount}(i) 就是答案。
时间复杂度 O(2NM)O(2^NM),代码实现如下:
CPP
#include<bits/stdc++.h>
using namespace std;
const int N=30; char s[N][N]; int w[N];
int main() {
    ios::sync_with_stdio(false),cin.tie(nullptr);
    int n,m,x,y,ans=0; cin>>n>>m>>x>>y;
    for(int i=1;i<=n;i++) cin>>(s[i]+1);
    for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) if(s[j][i]-'0') w[i]|=(1<<(j-1));
    for(int i=0;i<(1<<n);i++) {
        int sum=-x*__builtin_popcount(i);
        for(int j=1;j<=m;j++) sum+=max(__builtin_popcount(i&w[j])-y,0);
        ans=max(ans,sum);
    }
    cout<<ans;
    return 0;
}

评论

2 条评论,欢迎与作者交流。

正在加载评论...