【Aizu

-->Osenbei

直接写中文了

Descriptions:

给出n行m列的0、1矩阵,每次操作可以将任意一行或一列反转,即这一行或一列中0变为1,1变为0。问通过任意多次这样的变换,最多可以使矩阵中有多少个1。

Sample Input

2 5
0 1 0 1 0
1 0 0 0 1
3 6
1 0 0 0 1 0
1 1 1 0 1 0
1 0 1 1 0 1  
0 0

Sample Output

9
15
 
题目链接:
 

行数比较小,先不考虑对列的操作,将行数的所有情况举出来最多2^10种情况。对于已经固定了对行进行怎样的操作后,这种情况下对列的最优操作就是对每一列,如果此时1比0多就不变,不然就反转。实现在代码中就是一个for循环扫一遍。

AC代码:

#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#define mod 1000000007
#define eps 1e-6
#define ll long long
#define INF 0x3f3f3f3f
#define MEM(x,y) memset(x,y,sizeof(x))
#define Maxn 10005
using namespace std;
int ans;
int h,w;
int mp[15][Maxn];
void dfs(int x)
{
   if(x==h)
   {
       int sum=0;//这个图中1的最大个数
       for(int i=0;i<w;i++)
       {
           int tmpsum=0;//这一列中1的最大个数
           for(int j=0;j<h;j++)
           {
               if(mp[j][i]==1)
                    tmpsum++;
           }
           sum+=max(tmpsum,h-tmpsum);//若1的个数>0的个数,则这一列不翻转,否则反转
       }
       ans=max(ans,sum);//更新答案
       return;
   }
   dfs(x+1);
   for(int i=0;i<w;i++)//把第x行翻转
        mp[x][i]=!mp[x][i];
   dfs(x+1);
}
int main()
{
    while(cin>>h>>w,h+w)//输入行列
    {
        for(int i=0;i<h;i++)//输入数据
            for(int j=0;j<w;j++)
                cin>>mp[i][j];
        ans=0;//答案初始化为0
        dfs(0);
        cout<<ans<<endl;
    }
}
 
原文地址:https://www.cnblogs.com/sky-stars/p/11193897.html