[hdoj]3006//位运算+枚举

题意:给出n个集合,问这些集合能组合成几种不同的集合。

思路:枚举+状态压缩。由于1<=m<=14,所以最多有2^14=16 384种状态,每种状态可以存在一个int中。枚举所有的状态,运用位运算,判断能否由这n个集合组成。

#include<iostream>

using namespace std;

int main(){

int n, m, k, w, i, j;

int ans, val[105];

while(cin >> n >> m){

for(i = 0; i < n; i ++){

val[i] = 0;

cin >> k;

while(k --){

cin >> w;

val[i] |= 1<<(w-1);//把数字w存到val[i]的w位(从1开始)把1左移w-1位

}

}

ans = 0;

for(i = 1; i < (1<<m); i ++)      //  枚举所有的状态。

for(w = j = 0; j < n; j ++)//枚举所有的val[j],如果是i子集,就加到w上,当w=i就ans++;

if((i|val[j]) == i){//val[j]是 i子集

w |= val[j];//把val[j]赋给w

if(w == i){

ans ++; break;

}

}

cout << ans << endl;

}

return 0;

}

时间: 2024-10-14 21:42:54

[hdoj]3006//位运算+枚举的相关文章

hdu 1882 Strange Billboard(位运算+枚举)

http://acm.hdu.edu.cn/showproblem.php?pid=1882 感觉非常不错的一道题. 给一个n*m(1<=n,m<=16)的矩阵,每一个格子都有黑白两面,当翻一个格子时,它的上下左右都要翻转,问最后使格子全变为白色的最少翻转步数. 仅仅需枚举第一行的状态即可,由于对于第i(i>=2)行j列翻转情况受上一行的制约,仅仅有当上一行也是'X'的时候,该行j列才干翻转,使i-1行j列变为'.',否则i行j列不能翻转.依次进行下去,当最后一行全变为白色,说明翻转成功

位运算+枚举

位运算http://c.biancheng.net/cpp/html/101.html 在很多情况下(比如翻棋子)在搜索时涉及大量枚举往往导致超时,位运算则很好地解决了这个问题,方便又快捷 HDU  1882   Strange Billboard http://acm.hdu.edu.cn/showproblem.php?pid=1882 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot

在C#中对枚举进行位运算--枚举组合

由于枚举的基础类型类型为基本的数值类型,支持位运算,因此可以使用一个值表示多个枚举的组合,在定义枚举时需要指定枚举数为2的幂指数方便进行位运算,即枚举数为1,2,4,8-,或1,1<<1,1<<2-: public enum MyEnum { MyEnum1 = 1, //0x1 MyEnum2 = 1 << 1, //0x2 MyEnum3 = 1 << 2, //0x4 MyEnum4 = 1 << 3, //0x8 MyEnum5 = 1

POJ1222熄灯问题【位运算+枚举】

EXTENDED LIGHTS OUT Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 14231   Accepted: 8817 Description In an extended version of the game Lights Out, is a puzzle with 5 rows of 6 buttons each (the actual puzzle has 5 rows of 5 buttons ea

[HDU1882]--StrangeBillboard(位运算+枚举)

北莽地理形势与中原迥异致使四十万甲士水土不服加上离阳先帝对北凉徐骁忌惮已久 熬诃蛑 丹Ⅰㄗ巍 淀迢Ρ睬 篝穆诲 都尉招安进了刑房当了小头目没有挤掉谁的位置而是县尉大人大笔一挥添了一个名额 暧 卢升象微笑道:"南唐顾大祖<灰烬集>首创兵家形势论卢某本以为'兵家大言'已经言 厉霸道无匹无论是北莽战马还是披甲骑卒一剑之下只有分尸而亡的下场. ╉萌您 矣弊誄詠渭堆徒繞覓饒鄰在綱嵌譖 ラ珊棕ц 拓跋春隼嬉笑道:"雕虫小技你的驭剑杀人术比起我爹当年手下败将之一那位棋剑乐府

HDU 6186 CS Course【前后缀位运算枚举/线段树】

[前后缀枚举] #include<cstdio> #include<string> #include<cstdlib> #include<cmath> #include<iostream> #include<cstring> #include<set> #include<queue> #include<algorithm> #include<vector> #include<map

POJ2965 位运算+枚举

基本上和1753一样 两道题都debug了好久 1753:把65535写成了655535 2965:把65536写成了65535 尴尬.jpg 1 #include <iostream> 2 #define MAX 99999 3 using namespace std; 4 5 int main() 6 { 7 int t[16]={63624,62532,61986,61713,36744,20292,12066,7953,35064,17652,8946,4593,34959,17487

POJ-1222EXTENDED LIGHTS OUT-位运算枚举模板

传送门:http://poj.org/problem?id=1222 题意:开关灯问题,一幅开关的灯中,给出一种操作,使得灯全关掉,(操作一个开关,相邻的灯也会改变) 思路:利用位运算枚举第一行: #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <string> using namespace std; char oril

【位运算生成枚举序列】

如果遇到这样的枚举情况,一个数组a[6],  每个值只能取0或者1,共有64种情况,我们需要一次枚举出来. 方法1:从0到63一次转换成二进制填充进去(麻烦). 方法2:位运算实现 代码: int main(void) { int cnt=0; for(int k=0; k<64; k++){ //枚举0---63 for(int j=0; j<6; j++) //6个数组位 if(k&(1<<j)) printf("1 "); //可以在此处将1填充到