题意:
直接简化为这样的一个数学模型:列和行都可以翻转,所谓翻转就是该行或者该列0变成1、1变成0,求取整个数组1最多的数目。
题目解析
- 显然,这道题采用DFS来解决这种穷竭搜索的问题
- 为了方便数组计算,这里采用中的位数组来快速解决,因为正好题目中数组元素不是0就是1,而且涉及到翻转,正好对应了bitset的功能,如果不懂bitset,请参考这篇博客
bitset详解 - 因为题目中r范围远远小于列,那么我们就对行进行dfs,一行一行的来,每一行要么取要么不取,这也就是穷竭搜索,当所有行取遍之后进行列翻转,也就是对应列是0多还是1多,0多咱就翻转,1多咱就不翻转(这里翻转不翻转其实在代码实现部分没有必要,直接取0或者1数目最大值即可,没必要真的翻转)。
AC代码
#include<iostream>
#include<cstdio>
#include<queue>
#include<string>
#include<limits.h>
#include<bitset>
using namespace std;
int r,c;
bitset<10000> arr[50];
//int arr[10][10000];
int res;
void dfs(int row){
if(row==r){
int num=0;
int temp;
for(int j=0;j<c;j++){
temp=0;
for(int i=0;i<r;i++){
temp+=arr[i][j];
}
//取1表示该列不翻转,取0表示该列翻转
num=num+max(temp,r-temp);
}
res=max(res,num);
return;
}
//翻转
arr[row].flip();
dfs(row+1);
//不反转
arr[row].flip();
dfs(row+1);
}
int main(){
while(scanf("%d%d",&r,&c)!=EOF){
if(r==0&&c==0){
break;
}
for(int i=0;i<r;i++){
for(int j=0;j<c;j++){
int x;
scanf("%d",&x);
arr[i].set(j,x);
}
}
res=-1;
dfs(0);
printf("%d\n",res);
}
return 0;
}