矩阵游戏
矩阵游戏
题意
给出一个
每次操作为选择一行或一列,分数为该行/列的和,操作结束后该行/列整体减去
求最大分数。
思路
先有一个错误的贪心,即每次选择行和列中最大的一个操作,但这样有下面的 hack:
1 4 4 10
9 9 9 9
如果第一次选择一行操作,以后都必须加负数了。
而一列一列的操作就不会加负数。
然后发现行和列独立,对一个行操作完后列的相对大小不变,对一个列操作完后行的相对大小不变。
所以可以把单独取行和单独取列的答案先算出来。
记
可以用堆维护当前的行和,列和,取出最大后把
然后枚举
代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e3 + 5;
const int M = 1e6 + 5;
int n, m, k, p, a[N][N], f[M], g[M];
int h[M], l[M], ans = LLONG_MIN;
priority_queue <int> p1, p2;
signed main() {
freopen("matrix.in", "r", stdin);
freopen("matrix.out", "w", stdout);
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin >> n >> m >> k >> p;
for (int i = 1; i <= n; i ++) {
for (int j = 1; j <= m; j ++) {
cin >> a[i][j];
h[i] += a[i][j];
l[j] += a[i][j];
}
}
for (int i = 1; i <= n; i ++) p1.push(h[i]);
for (int i = 1; i <= k; i ++) {
f[i] = p1.top(); p1.pop();
p1.push(f[i] - p * m);
f[i] += f[i - 1];
}
for (int i = 1; i <= m; i ++) p2.push(l[i]);
for (int i = 1; i <= k; i ++) {
g[i] = p2.top(); p2.pop();
p2.push(g[i] - p * n);
g[i] += g[i - 1];
}
for (int i = 0; i <= k; i ++)
ans = max(ans, f[i] + g[k - i] - i * (k - i) * p);
cout << ans << "\n";
return 0;
}
本文来自博客园,作者:maniubi,转载请注明原文链接:https://www.cnblogs.com/maniubi/p/18526364,orz
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】