時間限制: 1000 ms 空間限制: 131072 KB 具體限制
Goto ProblemSet
題目描述
烤餅乾時兩面都要烤,而且一次可以烤行列個餅乾,當一面烤到規定時間時,機器會把整個翻過來以接着烤另一面。
有一天,正當機器準備翻餅乾時發生了地震,有一些餅乾被翻了過來,有一些沒有。幸運的是,地震過後你可以手工操作,一次可以同時翻若干行或者若干列,但不能單獨翻某一個餅乾。
寫一個程序計算通過翻轉使得最終翻過來的餅乾的數量得最大值。 例如下圖是地震之後的情況,黑點表示未翻轉,白點表示已經翻轉:
翻轉第一行後得到:
接着翻轉第列和第列得到下圖:
這樣可以使得個餅乾翻轉過來。
輸入
第行: 兩個整數和;
接下來行,每行個空格隔開的數,其中表示未被翻轉,表示已經翻轉。
輸出
輸出一個整數表示通過翻轉行列操作最多被翻轉的餅乾數量。
樣例輸入
樣例輸入1:
2 5
0 1 0 1 0
1 0 0 0 1
樣例輸入2:
3 6
1 0 0 0 1 0
1 1 1 0 1 0
1 0 1 1 0 1
樣例輸出
樣例輸出1:
9
樣例輸出2:
15
數據範圍限制
解題思路
因爲最多才十行,所以枚舉每一行,每一行若翻轉後白比黑多就翻。
代碼
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<iomanip>
#include<cmath>
using namespace std;
int n,m,ans,a[15][10010],f[10010];
void bsy(int x)
{
if(x==n+1)
{
for(int i=1; i<=m; i++)
{
int t=0;
for(int j=1; j<=n; j++)
t+=a[j][i];
if(t>n-t)
f[i]=f[i-1]+t;
else
f[i]=f[i-1]+n-t;
}
if(f[m]>ans)
ans=f[m];
return;
}
bsy(x+1);
for(int i=1; i<=m; i++)
if(a[x][i])
a[x][i]=0;
else
a[x][i]=1;
bsy(x+1);
for(int i=1; i<=m; i++)
if(a[x][i])
a[x][i]=0;
else
a[x][i]=1;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
scanf("%d",&a[i][j]);
}
bsy(1);
printf("%d",ans);
}