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 }
View Code

 

posted @ 2019-11-25 11:28  xiongbing  阅读(135)  评论(0)    收藏  举报