#枚举 #位运算 #贪心
题意
- n行m列矩阵(1<=n,m<=15),k次操作,每次消除一行or一列,将答案加上消除的值
- 求解最大答案
思路
- 对于只消除行和列,一定是消除行和和列和最高的k个
- 行和列同时选的时候,贪心的依次选最高行和列不能保证答案最优
选两次
9 10 1
1 1 1
1 20 9
- 所以既然混着选没法确定,那就枚举行的所有选法,然后再行确定的时候堆列进行贪心,用一个n位2进制表示行的选法,然后每次剔除所选行的元素计算每列的和
代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
int a[20][20];
int sum1[20],sum2[20];
int deal(int x){
int cnt=0;
while(x){
if(x&1) cnt++;
x>>=1;
}
return cnt;
}
signed main(){
int n,m,k;
cin >> n >> m >> k;
if(k>n||k>m) k=n;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin >> a[i][j];
sum1[i]+=a[i][j];
}
}
int res=0;
for(int st=0;st<=(1<<n)-1;st++){
int cnt=deal(st);
int ans=0;
if(cnt>k) continue;
for(int i=1;i<=n;i++){
if((st>>i-1)&1){
ans+=sum1[i];
}
}
// cout << st << ' ' << cnt << ' '<< ans << endl;
memset(sum2,0,sizeof(sum2));
for(int i=1;i<=n;i++){
if((st>>i-1)&1) continue;
for(int j=1;j<=m;j++){
sum2[j]+=a[i][j];
}
}
sort(sum2+1,sum2+m+1,greater());
for(int i=1;i<=k-cnt;i++){
ans+=sum2[i];
}
res=max(res,ans);
}
cout << res << endl;
return 0;
}