http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0525
题意:药药!切克闹! 煎饼果子来一套!有一个烤饼器可以烤r行c列的煎饼,煎饼可以正面朝上(用1表示)也可以背面朝上(用0表示)。一次可将同一行或同一列的煎饼全部翻转。现在需要把尽可能多的煎饼翻成正面朝上,问最多能使多少煎饼正面朝上?
输入:多组输入,每组第一行为二整数r, c (1 ≤ r ≤ 10, 1 ≤ c ≤ 10 000),剩下r行c列表示煎饼初始状态。r=c=0表示输入结束。
输出:对于每组输入,输出最多能使多少煎饼正面朝上
注意数据范围!!从这里联想到解题方法,顺带查阅bitset的相关资料!(笔者前几篇博客有)
最近做的题感觉bfs什么时候都能够插一脚哈!!
.
.
.
.
.
.
.
.
.
.
分析:这个是二维的穷举,因为列数比较多行数比较少,所以可对行做深度优先遍历穷举所有行的情况。这里用bitset保存每一行的情况,对于行的翻装,只需要用自带的flip函数。对于每一行都确定动作时,统计每一列翻时会出现的正面朝上的值以及不翻时的值,取较大数。此时为行动作确定时,列动作可以做到的最优值。因此穷举所有行情况即可求出实际最优值。
#include <cstdio> #include <algorithm> #include <bitset> using namespace std; const int MAX_R = 10; const int MAX_C = 10000; //input int R, C; bitset<MAX_C> a[MAX_R]; int ans; void dfs(int k){ if(k == R){ //row certain int result = 0; //cur max value for(int j = 0; j < C; j ++){ int upNum = 0; //up numbers without fliping for(int i = 0; i < R; i ++){ if(a[i][j]) upNum ++; } result += max(upNum, R - upNum); } ans = max(ans, result); return; } //without fliping dfs(k + 1); //·flip a[k].flip(); dfs(k + 1); } void solve(){ ans = 0; dfs(0); printf("%d\n", ans); } int main(int argc, char const *argv[]){ while(scanf("%d %d", &R, &C)){ if(R == 0 && C == 0) break; for(int i = 0; i < R; i ++){ for(int j = 0; j < C; j ++){ bool tmp; scanf("%d", &tmp); a[i][j] = tmp; } } solve(); } return 0; }
AOJ-0525 Osenbei-翻煎饼(穷竭搜索,BFS,BITSET)
原文地址:http://blog.csdn.net/acm_10000h/article/details/40988419