题目描述
NOIP烤饼干时两面都要烤,而且一次可以烤R(1<=R<=10)行C(1<=C<=10000)列个饼干,当一面烤到规定时间时,机器会把整个翻过来以接着烤另一面。
有一天,正当机器准备翻饼干时发生了地震,有一些饼干被翻了过来,有一些没有。幸运的是,你可以手工操作,一次可以同时翻若干行或者若干列,但不能单独翻某一个饼干。
写一个程序计算通过翻转使得最终翻过来的饼干的数量得最大值。
例如下图是地震之后的情况,黑点表示未翻转,白点表示已经翻转:
翻转第一行后得到:
接着翻转第1列和第5列得到下图:
这样可以使得9个饼干翻转过来。
输入
第1行: 两个整数R和C(1<=R<=10,1<=C<=10000);接下来R行,每行C个空格隔开的数,其中aij=1表示未被翻转,0表示已经翻转。
输出
输出一个整数表示通过翻转行列操作最多被翻转的饼干数量。
Code
#include<cstdio>
#include<iostream>
using namespace std;
int y[10001],n,m;
long long ans,mx;
int amount(unsigned int x)
{
unsigned int c = 0 ;
for (c = 0;x;++c)
{
x &= (x - 1);
}
return c ;
}
int main()
{
cin >> n >> m;
int tmp;
for(int i = 1;i <= n;i++)
for(int j = 1;j <= m;j++)
{
cin >> tmp;
y[j] = (y[j] << 1) + tmp;
}
rp(i,0,(1<<n)-1)
for(int i = 0;i <= (1 << n) - 1;i++)
{
mx = 0;
for(int j = 1;j <= m;j++)
{
int p = amount(i ^ y[j]);
mx = mx + max(p,n - p);
}
ans = max(mx,ans);
}
cout << ans;
}