题意是有一个赋有非负数的矩阵,每次可以将某一行or某一列替换成某个数值,可以替换<=k次,问如何替换能使得矩阵总和最大,输出最大值。
一开始想的是简单的贪心:比如找当前收益最大的行或者列来替换。这样的问题在于:替换行必然影响列,同理列影响行,就是说当前的贪心会影响之后的决策,不可行。
因为行最多10行,所以用dfs枚举行替换与否,然后再贪心地找收益最大的列来替换。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
const ll maxN=2e2+5;
ll G[maxN][maxN], T[maxN][maxN], C[maxN];
bool used[maxN];
ll n, m, x, k, ans;
void calc() {
ll us = 0;
memcpy(T, G, sizeof G);
FOR(i, 1, n) if (used[i]) {
++us;
FOR(j, 1, m) T[i][j] = x;
}
ll sy = k - us;
memset(C, 0, sizeof C);
FOR(j, 1, m) FOR(i, 1, n) C[j] += T[i][j];
ll aft = n * x;
FOR(s, 1, sy) {
ll idx = min_element(C + 1, C + 1 + m) - C;
if (C[idx] >= aft) break;
C[idx] = aft;
FOR(i, 1, n) T[i][idx] = x;
}
ll t = 0;
FOR(i, 1, n) FOR(j, 1, m) t += T[i][j];
ans = max(ans, t);
}
void dfs(ll r, ll tk) {
if (tk > k) return;
if (r > n) calc();
else {
used[r] = 1;
dfs(r + 1, tk + 1);
used[r] = 0;
dfs(r + 1, tk);
}
}
int main () {
cin >> n >> m >> x >> k;
memset(used, 0, sizeof used);
FOR(i, 1, n)
FOR(j, 1, m) cin >> G[i][j];
ans = 0;
dfs(1, 0);
cout << ans << '
';
return 0;
}