AOJ 0525 - Osenbei

ヒント通り,Rの小ささに注目します.
縦の裏返し方は2^R通りです.(各々について裏返すか裏返さないかの2通りがある)
横は裏返した後に,出荷できる煎餅を最大にするようにすればいい.
順番は気にしなくていいのと思ったけど,ある煎餅に対し,表裏を決めるのは回数なので関係ない.

#include<iostream>

int table[10][10000], R, C;

int reverse(int S){//S: 縦の裏返すところの集合
	for(int i=0;i<R;i++){
		if(S >> i & 1){
			for(int j=0;j<C;j++){
				table[i][j] = !table[i][j];
			}
		}
	}

	int res = 0;
	for(int i=0;i<C;i++){
		int white = 0, black = 0;
		for(int j=0;j<R;j++){
			white += !table[j][i];
			black += table[j][i];
		}
		res += std::max(white, black);
	}

	for(int i=0;i<R;i++){
		if(S >> i & 1){
			for(int j=0;j<C;j++){
				table[i][j] = !table[i][j];
			}
		}
	}

	return res;
}

int main(){
	while(std::cin >> R >> C, R){
		for(int i=0;i<R;i++){
			for(int j=0;j<C;j++){
				std::cin >> table[i][j];
			}
		}

		int res = 0;
		for(int S=0;S<1<<R;S++){
			res = std::max(res, reverse(S));
		}

		std::cout << res << std::endl;
	}
}