AOJ 0525 Osenbei
由于n比较小,所以可以对行DFS,那列呢?其实列很好处理,对每一列统计1的个数或者0的个数,保留最大者即是最大的正面个数,试想如果当前列正面个数多,那这一列就不翻面就好了,如果反面多,那么将该列翻面即可使得原先反面变成正面。所以对列直接统计即可。
这题需要注意的是无论哪一行或者那一列先翻面都是无谓的,不影响结果,即翻面的顺序不影响结果,只考虑该行或该列是否要翻面即可,所以可以直接DFS。
代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 5 using namespace std; 6 7 int r,c; 8 int maze[15][10005]; 9 int maxRes; 10 11 void rev(int n){ 12 for(int i=0;i<c;i++){ 13 maze[n][i]=maze[n][i]^1; 14 } 15 } 16 17 int cal(){ 18 int sum=0; 19 for(int j=0;j<c;j++){ 20 int cou1=0; 21 for(int i=0;i<r;i++){ 22 cou1+=maze[i][j]; //统计1的个数 23 } 24 sum+=max(cou1,r-cou1); 25 } 26 return sum; 27 } 28 29 void dfs(int n){ 30 if(n==r){ 31 maxRes=max(maxRes,cal()); 32 return; 33 } 34 rev(n); 35 dfs(n+1); 36 rev(n); 37 dfs(n+1); 38 } 39 40 void solve(){ 41 scanf("%d%d",&r,&c); 42 while(r!=0||c!=0){ 43 maxRes=0; 44 for(int i=0;i<r;i++){ 45 for(int j=0;j<c;j++){ 46 scanf("%d",&maze[i][j]); 47 } 48 } 49 dfs(0); 50 printf("%d\n",maxRes); 51 scanf("%d%d",&r,&c); 52 } 53 } 54 55 int main(){ 56 solve(); 57 return 0; 58 }
另一总,思路一样,但有点没看懂的方法
1 #include <iostream> 2 #include <bitset> 3 #include <algorithm> 4 5 using namespace std; 6 7 bitset<10000> cookie[10]; 8 9 ///////////////////////////SubMain////////////////////////////////// 10 int main(int argc, char *argv[]) 11 { 12 13 int R, C; 14 while(cin >> R >> C && R > 0) 15 { 16 int i, j; 17 for (i = 0; i < R; ++i) 18 { 19 for (j = 0; j < C; ++j) 20 { 21 bool upwards; 22 cin >> upwards; 23 cookie[i][j] = upwards; 24 } 25 } 26 27 // 在横向一共有2^R种变换 28 int permute_r = 1 << R; 29 int result = 0; 30 for (i = 0; i < permute_r ; ++i) 31 { 32 // 完成当前的变换 33 for (j = 0; j < R; ++j) 34 { 35 // 这一行是否应当翻个面 36 if (i & (1 << j)) 37 { 38 cookie[j].flip(); 39 } 40 } 41 42 43 // 对每一列分别算出朝上和朝下的煎饼个数,取其最大值 44 int possible_answer = 0; 45 for (j = 0; j < C; ++j) 46 { 47 int up_cookie_count = 0; 48 for (int k = 0; k < R; ++k) 49 { 50 if (cookie[k][j]) 51 { 52 ++up_cookie_count; 53 } 54 } 55 possible_answer += max(up_cookie_count, R - up_cookie_count); 56 } 57 // 结果取最大值 58 result = max(result, possible_answer); 59 60 // 复原 61 for (j = 0; j < R; ++j) 62 { 63 if (i & (1 << j)) 64 { 65 cookie[j].flip(); 66 } 67 } 68 } 69 cout << result << endl; 70 } 71 72 return 0; 73 }
浙公网安备 33010602011771号