NC200190 矩阵消除游戏
题目
题目描述
牛妹在玩一个名为矩阵消除的游戏,矩阵的大小是 行 列,第 行第 列的单元格的权值为 ,牛妹可以进行 个回合的游戏,在每个回合,牛妹可以选择一行或者选择一列,然后将这一行或者这一列的所有单元格中的权值变为 ,同时牛妹的分数会加上这一行或者这一列中的所有单元格的权值的和。
牛妹想最大化她的得分,球球你帮帮她吧!
输入描述
第一行三个整数
接下来 行每行 个整数表示矩阵中各个单元格的权值。
输出描述
输出一个整数表示牛妹能获得的最大分数。
示例1
输入
3 3 2 101 1 102 1 202 1 100 8 100
输出
414
备注
,
题解
知识点:枚举,贪心,位运算。
首先发现直接贪心是不可行的,每次清零会导致行列信息的都发生变化。考虑枚举行或列,这里选择枚举行的选择情况。
一共 种情况,用一个整型变量保存选择的状态即可。
在行选择完之后,对列贪心地从大开始选,注意选择的列数量只能是 , 表示选择的行数量,由于剩余数量可能超过列数 ,因此用 限制。
在累加过程可以用前缀和预处理,可以节省一点时间。
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> using namespace std; int a[20][20], r[20], c[20], ccur[20]; int cnt(int n) { int ans = 0; while (n) { ans++; n &= n - 1; } return ans; } int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int n, m, k; cin >> n >> m >> k; for (int i = 0;i < n;i++) for (int j = 0;j < m;j++) cin >> a[i][j]; for (int i = 0;i < n;i++) for (int j = 0;j < m;j++) r[i] += a[i][j]; for (int i = 0;i < m;i++) for (int j = 0;j < n;j++) c[i] += a[j][i]; int ans = 0; for (int i = 0;i < (1 << n);i++) { if (cnt(i) > k) continue; memcpy(ccur, c, sizeof(c)); int sum = 0; for (int j = 0;j < n;j++) { if ((i >> j) & 1) { sum += r[j]; for (int u = 0;u < m;u++) ccur[u] -= a[j][u]; } } sort(ccur, ccur + m, [&](int a, int b) {return a > b;}); for (int j = 0;j < min(k - cnt(i), m);j++) sum += ccur[j]; ans = max(ans, sum); } cout << ans << '\n'; return 0; }
本文来自博客园,作者:空白菌,转载请注明原文链接:https://www.cnblogs.com/BlankYang/p/16383127.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧