思路
枚举行(或列),对列(或行)贪心即可,注意枚举的起点和终点
代码
#include <bits/stdc++.h>
#define ios std::ios::sync_with_stdio(false);std::cin.tie(0)
using namespace std;
int M[20][20];
int LL[20]; //行列总和
int CC[20];
bool cmp(int a,int b){
return a > b;
}
int main(){
ios;
int n,m,k, ans = 0;
cin>>n>>m>>k;
//获取矩阵
for(int i = 1;i <= n;i++){
for(int j = 1;j <= m;j++){
cin>>M[i][j];
LL[i] += M[i][j];
CC[j] += M[i][j];
}
}
//考虑枚举子集,先枚举行
for(int i = 0;i < (1 << n);i++){
//维护行列和
int tmpC[20],tmpk = k,tmpAns = 0;
for(int a = 1;a <= m;a++) tmpC[a] = CC[a];
for(int j = 1;j <= n;j++){
if(((1 << (j-1)) & i) && tmpk > 0){
//选中行
tmpAns += LL[j];
tmpk--;
//相关行置0,更新列
for(int a = 1;a <= m;a++) tmpC[a] -= M[j][a];
}
}
//贪心选择列,同时维护全局最大分数
sort(tmpC+1,tmpC+m+1,cmp);
for(int a = 1;a <= m;a++){
if(tmpk > 0){
tmpAns += tmpC[a];
tmpk--;
}else break;
}
ans = max(ans,tmpAns);
}
cout<<ans;
return 0;
}