思路
这个题其实不能贪心, 看了下 M 和 N 更像是一道暴力搜索的题目
怎么搜索呢
用 01状态压缩, 枚举选哪些行, 然后选剩下的列(取值最大的几个就好)
记录两个值, 一个是行和sum (分开每行记也行) 另一个是列和 sumrow[r] 记录每一列的 列和
然后枚举找最大值即可 , 时间复杂度 O(2^n * n * m ) 可以接受
ac 代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
const int inf = INT_MAX;
typedef pair<int, int> pii;
typedef priority_queue<int, vector<int>, greater<int>> small_heap;
#define int long long
int n, m, k;
int a[20][20];
int b[20][20];
int ans;
int sumrow[20];
int cnt;
bool cmp(int a, int b)
{
return a > b;
}
int get(int st)
{
memcpy(b, a,sizeof a );
cnt = 0;
int sum = 0;
memset(sumrow, 0, sizeof sumrow);
for (int c = 1; c <= n; c++)
{
if (st >> (c - 1) & 1)
{
cnt++;
for (int r = 1; r <= m; r++){
sum += b[c][r];
b[c][r] = 0;
}
}
else
{
for (int r = 1; r <= m; r++)
sumrow[r] += b[c][r];
}
}
return sum;
}
int32_t main()
{
int su = 0;
scanf("%d%d%d", &n, &m, &k);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
{
scanf("%d", &a[i][j]);
su += a[i][j];
}
if (k >= n || k >= m )
{
printf("%d\n" , su);
return 0;
}
for (int s = 0; s <= ((1 << n) - 1); s++)
{
int sum = get(s);
int rest = k - cnt;
if (rest < 0)
continue;
sort(sumrow + 1, sumrow + m + 1, cmp);
for (int i = 1; i <= rest; i++)
sum += sumrow[i];
ans = max(ans, sum);
}
printf("%d\n", ans);
return 0;
}