题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3006
题意:给定一些集合,求这些集合所能组合的集合个数。
分析:这题就是用一个二进制数保存一个集合的元素 比如一个集合中有两个元素 1 3 那就用5 (101)表示这个集合
就是用0 1 来表示这个集合中一个数存不存在 再比如 一个集合有 三个元素 1 4 5 就在这几个位子上标为1,那就
用25 (11001)来表示这个集合!在借助于位运算的或( | )就可已达到合并集合的目的,比如一个集合(1 4 )
和一个集合(1 2 3)进行合并 那就是 (9)1001 | 111(7)=1111 就是15 这样就将重复的部分覆盖了。新的集合就用15来表示!最大就是(11111111111111)2^15-1来表示一个集合!
#include <cstdio> #include <cstring> #include <cmath> #include <iostream> #include <algorithm> #include <queue> #include <cstdlib> #include <vector> #include <set> #include <map> #define LL long long #define mod 19890907 #define inf 0x3f3f3f3f #define N 10010 using namespace std; int vis[1<<15]; int main() { int n,m; while(scanf("%d%d",&n,&m)>0) { memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) { int num,x,res=0; scanf("%d",&num); while(num--) { scanf("%d",&x); res|=1<<(x-1); } vis[res]=1; for(int j=0;j<(1<<m);j++) if(vis[j])vis[j|res]=1; } int ans=0; for(int i=0;i<(1<<m);i++)if(vis[i])ans++; printf("%d ",ans); } }