题目
给出n行m列的0、1矩阵,每次操作可以将任意一行或一列反转,即这一行或一列中0变为1,1变为0。问通过任意多次这样的变换,最多可以使矩阵中有多少个1。
N >= 10 M <= 10000
题解思路
行比较少,我们可以枚举行的变换来确定列。
当列的1数目大于一半时不翻转,小于等于时翻转,等于翻转就涉及到奇数取整的问题,例如 1 3 3/2 = 1 .但如果翻转了就是2了,所以等于也要翻转。
这里我用二进制枚举,建议用二进制枚举时数组从0开始,方便后面枚举。
AC代码
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int mp[12][10010];
int main ()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
if (n == 0 )
break;
int ans = 0 ;
for (int i = 1 ; i <= n ; i++ )
{
for (int j = 1 ; j <= m ; j++ )
{
scanf("%d",&mp[i][j]);
}
}
for (int i = 0 ; i< 1<<n ; i++ )
{
int t = 0 ;
for (int j = 1 ; j <= m ; j++ )
{
int p = 0 ;
for (int k = 1 ; k <= n ; k++ )
{
if ( mp[k][j] == 1 )
{
if ( !(i >>(k-1) & 1))
p++;
}else
{
if (i >>(k-1) & 1)
p++;
}
}
if ( p <= n/2 )
p = n - p;
t+= p;
}
ans = max(ans,t);
}
printf("%d\n",ans);
}
}