分两种情况讨论,1是直接选行,2是行选了还有剩下的,那么直接去找列中最大的。使用二进制枚举所有情况最后去最大值就行具体看代码
#include <bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
int n, m, k;
int a[20][20];
int ans = 0;
int temp[20];
int pre[20];
int cal(int x){
int res = 0;
while(x){
if(x & 1) res ++;
x >>= 1;
}
return res;
}
bool cmp(int a, int b){
return a > b;
}
int handle(){
int res = 0;
for(int i = 0; i < (1 << n); i ++){
int te = 0;
int cnt = cal(i);//计算有多少1;
if(cnt < k){//选了行之后还要选列
for(int j = 1; j <= n; j ++){
if((i >> (j - 1)) & 1){//这一行要选
for(int p = 1; p <= m; p ++){
te += a[j][p];
}
}
}
//加上多余的列
memset(pre, 0, sizeof pre);
for(int p = 1; p <= m; p ++){
for(int j = 1; j <= n; j ++){
if((i >> (j - 1)) & 1) continue;
pre[p] += a[j][p];
}
}
sort(pre + 1, pre + 1 + m, cmp);
for(int j = 1; j <= k - cnt; j ++){
te += pre[j];
//cout << pre[j] << endl;
}
//cout << te << " " << i << endl;
}else{//直接选行就足够了
for(int j = 1; j <= n; j ++){
temp[j] = 0;
if((i >> (j - 1)) & 1){//这一行要选
for(int p = 1; p <= m; p ++){
temp[j] += a[j][p];
}
}
}
sort(temp + 1, temp + 1 + n, cmp);//从大到小排序
//选择k个
for(int i = 1; i <= k; i ++){
te += temp[i];
}
}
res = max(res, te);//每次选择最大的
}
return res;
}
int main(){
cin >> n >> m >> k;
for(int i = 1; i <= n; i ++){
for(int j = 1; j <= m; j ++){
int x;
cin >> x;
a[i][j] = x;
}
}
if(k >= n || k >= m){
for(int i = 1; i <= n; i ++){
for(int j = 1; j <= m; j ++){
ans += a[i][j];
}
}
}else{
ans = handle();
}
cout << ans << endl;
return 0;
}