首页 > 其他 > 详细

Fliptile POJ - 3279(状态压缩)

时间:2019-10-13 13:01:16      阅读:72      评论:0      收藏:0      [点我收藏+]

题意:给你一个n * m的矩阵,元素为0/1, 求把所有的元素变成0所需要的最少操作。(每对一个格子操作,该十字格的元素反转)

分析:一看数据量 <= 15, 就有点状态压缩的感jio。从小到大枚举第一行的操作,因为第一行的操作决定了后面所有的操作,所以最后判断对于第一行的操作是不是符合题意即可。

代码:

 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 }

 

Fliptile POJ - 3279(状态压缩)

原文:https://www.cnblogs.com/liuwenhan/p/11665879.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!