链接
https://ac.nowcoder.com/acm/contest/4090/C
题意
有一个 n × m n \times m n×m 的矩阵,进行 k k k 次操作,每次可以选一行(列)使 r e s res res 加上这一行(列)的权值和并将这一行(列)的单源格的权值都变为 0 0 0,求 r e s res res 的最大值
思路
首先 k = min ( k , min ( n , m ) ) k=\min(k,\min(n,m)) k=min(k,min(n,m)),因为当 k = n ∣ ∣ k = m k=n∣∣k=m k=n∣∣k=m 时我们就可以将所有行(列)全部选择
状压枚举选择了哪几列,再计算每一行中剩余元素的和进行排序,在根据值从大到小选即可
代码
#include<bits/stdc++.h>
using namespace std;
const int N=20;
int n,m,t,a[N][N],sum[N],ans;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>m>>t;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
cin>>a[i][j];
t=min(t,min(n,m));
for(int i=0;i<(1<<m);i++) {
int cnt=__builtin_popcount(i);
int res=0;
if(cnt>t) continue;
memset(sum,0,sizeof sum);
for(int j=0;j<n;j++)
for(int k=0;k<m;k++) {
if(i&1<<k) res+=a[j][k];
else sum[j]+=a[j][k];
}
sort(sum,sum+n);
for(int j=n-1,k=t-cnt;k;j--,k--) res+=sum[j];
ans=max(ans,res);
}
cout<<ans<<endl;
return 0;
}