UVa11464 Even Parity (枚举子集)

链接:http://acm.hust.edu.cn/vjudge/problem/24665分析:枚举第0行的情况,接下来可以根据第0行计算出第1行,根据第1行计算出第2行...方法是当确定B[r][c]是0还是1时(前提要合法),根据B[r-1][c]的上,左,右3个元素之和来判断,如果出现将原来是1的变为0则不合法返回INF,最后统计下原来是0后来变为1的个数cnt,然后返回更新ans被改变元素的最小个数即可。
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5
 6 const int INF = 1e9;
 7 const int maxn = 15 + 5;
 8
 9 int n, A[maxn][maxn], B[maxn][maxn];
10
11 int check(int s) {
12     for (int c = 0; c < n; c++)
13         if (s & (1 << c)) B[0][c] = 1;
14         else if (A[0][c]) return INF;
15         else B[0][c] = 0;
16     for (int r = 1; r < n; r++)
17         for (int c = 0; c < n; c++) {
18             int sum = 0;
19             if (r > 1) sum += B[r - 2][c];
20             if (c > 0) sum += B[r - 1][c - 1];
21             if (c < n - 1) sum += B[r - 1][c + 1];
22             B[r][c] = sum % 2;
23             if (A[r][c] == 1 && B[r][c] == 0) return INF;
24         }
25     int cnt = 0;
26     for (int r = 0; r < n; r++)
27         for (int c = 0; c < n; c++)
28             if (A[r][c] != B[r][c]) cnt++;
29     return cnt;
30 }
31
32 int main() {
33     int T;
34     scanf("%d", &T);
35     for (int kase = 1; kase <= T; kase++) {
36         scanf("%d", &n);
37         for (int r = 0; r < n; r++)
38             for (int c = 0; c < n; c++)
39                 scanf("%d", &A[r][c]);
40         int ans = INF;
41         for (int s = 0; s < (1 << n); s++)
42             ans = min(ans, check(s));
43         if (ans == INF) ans = -1;
44         printf("Case %d: %d\n", kase, ans);
45     }
46     return 0;
47 }
时间: 2024-10-12 20:38:04

UVa11464 Even Parity (枚举子集)的相关文章

【UVA】11464-Even Parity(二进制枚举子集)

枚举第一行的所有可能情况,之后根据上面行计算下面行(判断是否冲突),获得最终结果. 14058243 11464 Even Parity Accepted C++ 0.275 2014-08-18 05:14:15 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<vector> #include<stack> #inc

11825 - Hackers&#39; Crackdown 状态压缩 dp 枚举子集

11825 - Hackers' Crackdown 状态压缩 dp 枚举子集 ACM 题目地址:11825 - Hackers' Crackdown 题意: 有一个由编号0~n-1的n台计算机组成的网络,一共有n种服务,每台计算机上都运行着全部服务,对于每台计算机,你可以选择停止一项服务,这个行为会导致与这台计算机和与他相连的其他计算机上的这项服务都停止(原来已经停止的继续保持停止状态).求最多能使多少个服务瘫痪(即没有任何一台计算机在运行这项服务). 分析: 题目说白了,就是: 把n个集合p

UVA 11825 - Hackers&amp;#39; Crackdown 状态压缩 dp 枚举子集

UVA 11825 - Hackers' Crackdown 状态压缩 dp 枚举子集 ACM 题目地址:11825 - Hackers' Crackdown 题意: 有一个由编号0~n-1的n台计算机组成的网络,一共同拥有n种服务,每台计算机上都执行着所有服务,对于每台计算机,你能够选择停止一项服务,这个行为会导致与这台计算机和与他相连的其它计算机上的这项服务都停止(原来已经停止的继续保持停止状态). 求最多能使多少个服务瘫痪(即没有不论什么一台计算机在执行这项服务). 分析: 题目说白了.就

UVa 11025 The broken pedometer【枚举子集】

题意:给出一个矩阵,这个矩阵由n个数的二进制表示,p表示用p位二进制来表示的一个数 问最少用多少列就能将这n个数区分开 枚举子集,然后统计每一种子集用了多少列,维护一个最小值 b[i]==1代表的是选择了这一列 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include <cmath> 5 #include<stack> 6 #include<vector&g

HDU Untitled(状压DP OR dfs枚举子集)

Untitled Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 325    Accepted Submission(s): 169 Problem Description There is an integer a and n integers b1,-,bn. After selecting some numbers from b

1151 - Buy or Build(二进制枚举子集 + 并查集)

这题LRJ书上翻译的有问题,书上说两点之间的cost是两点的欧几里得距离,而题目要求两点的距离是两点欧几里得距离的平方. 其余就没什么好说的了,裸的并查集,需要注意的就是二进制枚举子集的问题. 二进制枚举子集: for(int i = 0 ; i < (1 << s) ; i++){ /*s是集合元素的个数*/ for(int j = 0 ; j < s ; j++){ if(!(s >> j) & 1) continue; else{ } } } 140548

HDU 5616 Jam&#39;s balance(暴力枚举子集)

题目链接:点击打开链接 题意:有一个没有游标的天平,和n个秤砣,m个询问, 每次一个k,问可否秤出k这个重量. 秤砣可以放两边. 思路:因为n最大20, 暴力枚举子集. 因为可以放两边, 所以每次再跑一遍, 减去每个的重量, 将答案保存. 比赛的时候忘了限制边界,虽然过了终测数据, 却被人用大数据hack了(RE), 还是自己程序写的不够鲁棒, 思考的不完善. 细节参见代码: #include<cstdio> #include<cstring> #include<algori

hdu 1557 权利指数 ( 二进制枚举子集) 解题心得

原题: Description 在选举问题中,总共有n个小团体,每个小团体拥有一定数量的选票数.如果其中m个小团体的票数和超过总票数的一半,则此组合为“获胜联盟”.n个团体可形成若干个获胜联盟.一个小团体要成为一个“关键加入者”的条件是:在其所在的获胜联盟中,如果缺少了这个小团体的加入,则此联盟不能成为获胜联盟.一个小团体的权利指数是指:一个小团体在所有获胜联盟中成为“关键加入者”的次数.请你计算每个小团体的权利指数. Input 输入数据的第一行为一个正整数T,表示有T组测试数据.每一组测试数

UVA 1354 Mobile Computing(天平难题,枚举子集,递归,好题*)

1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 5 /** 6 思路:在每一个根节点枚举左右子树 7 8 学习: 9 (1)枚举子集的方法 例如 枚举 s = 100101 的子集 10 for(int l = (s-1)&s , l > 0 ; l = (l-1) & s){ 11 int r = s ^ l; 12 (2)思考:如何表示 左边距离 右边距离 . 该点的