hdu 3006 The Number of set
http://acm.hdu.edu.cn/showproblem.php?pid=3006
状态压缩,位运算!看到别人题解里有这题,就看到这题是用状态压缩来做的,当时我想都不想就马上把状态压缩的代码打上去。不过我打着打着才发现好像不是那么简单,就算压缩了也不能搜索啊。。。囧!然后我又陷入一片窘境。。。。。
后来想到了可以改变思考的方向,不是找集合合并后会产生怎样的集合。因为元素的个数是限定的,所以集合的上限是确定的,因此我想到了搜索每种情况是否可能达成。
代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <cstring> 3 #include <cassert> 4 #include <algorithm> 5 #include <vector> 6 7 using namespace std; 8 9 typedef vector<int> vi; 10 11 vi Set; 12 13 int deal(int n, int m){ 14 Set.clear(); 15 for (int i = 0; i < n; i++){ 16 int k, a, tmp; 17 18 scanf("%d", &k); 19 tmp = 0; 20 while (k--){ 21 scanf("%d", &a); 22 tmp |= 1 << (a - 1); 23 } 24 Set.push_back(tmp); 25 } 26 int ret = 0, test; 27 28 for (int i = 0, endi = 1 << m; i < endi; i++){ 29 test = 0; 30 for (vi::iterator ii = Set.begin(); ii != Set.end(); ii++){ 31 if ((i | *ii) == i){ 32 test |= *ii; 33 if (test == i){ 34 ret++; 35 break; 36 } 37 } 38 } 39 } 40 41 return ret; 42 } 43 44 int main(){ 45 int n, m; 46 47 while (~scanf("%d%d", &n, &m)){ 48 printf("%d\n", deal(n, m)); 49 } 50 51 return 0; 52 }
——written by Lyon