Fliptile POJ - 3279 (state compression)

Meaning of the questions: to give you a n * m matrix elements 0/1, seeking to become the least of all the elements required for operation 0. (Each operation on a grid, the grid elements in cross-inverted)

Analysis: a look at the amount of data <= 15, a little compressed state sense jio. From small to large enumeration of the first line, because the operation of the first line determines the overall operation of the back, the final judgment for the operation of the first row is not consistent with the meaning of problems can be.

Code:

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <map>
 5 using namespace std;
 6 const int maxn = 20;
 7 int now;
 8 int g[maxn][maxn];
 9 int cnt[maxn][maxn];
10 int res[(1 << 15) + 10][maxn][maxn];
11 
12 int main()
13 {
14     int n, m; cin >> n >> m;
15     for (int i = 1; i <= n; i++)
16         for (int j = 1; j <= m; j++)
17             cin >> g[i][j];
18     int minn = 1e9;
19     for (now = 0; now < (1 << m); now++)
20     {
21         int tmp = now;
22         int ope = 0;
23         memset(cnt, 0, sizeof(cnt));
24         for (int i = m; i >= 1; i--)
25         {
26             if (tmp & 1)
27             {
28                 ope++;
29                 cnt[1][i]++, cnt[2][i]++;
30                 if (i >= 2) cnt[1][i - 1]++;
31                 if (i <= m - 1) cnt[1][i + 1]++;
32                 res[now][1][i]++;
33             }
34             tmp >>= 1;
35         }
36         for(int i = 2; i <= n; i++)
37             for (int j = 1; j <= m; j++)
38             {
39                 if ((g[i - 1][j] + cnt[i - 1][j]) & 1)
40                 {
41                     ope++;
42                     cnt[i][j]++, cnt[i - 1][j]++, cnt[i + 1][j]++;
43                     if (j >= 2) cnt[i][j - 1]++;
44                     if (j <= m - 1) cnt[i][j + 1]++;
45                     res[now][i][j]++;
46                 }
47             }
48         int flag = 0;
49         for(int i = 1; i <= m; i++)
50             if ((g[n][i] + cnt[n][i]) & 1)
51             {
52                 flag = 1;
53                 break;
54             }
55         if (!flag)
56             res[now][0][0] = ope, minn = min(minn, ope);
57         else res[now][0][0] = -1;
58     }
59     for(int i = 0; i < (1 << 15); i++)
60         if (res[i][0][0] == minn)
61         {
62             for (int j = 1; j <= n; j++)
63                 for (int k = 1; k <= m; k++)
64                     printf("%d%c", res[i][j][k], k == m ? '\n' : ' ');
65             return 0;
66         }
67     printf("IMPOSSIBLE");
68 }

 

Guess you like

Origin www.cnblogs.com/liuwenhan/p/11665879.html