牛客练习赛 58 C. 矩阵消除游戏

链接

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=nk=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;
}
©️2020 CSDN 皮肤主题: 创作都市 设计师:CSDN官方博客 返回首页