HDU 3006 The Number of set(位运算 状态压缩)
2013-08-26 19:11
465 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3006
题目大意:给定n个集合,每个集合都是由大于等于1小于等于m的数字组成,m最大为14。由给出的集合可以组成多少个不同的集合。
输入描述:第一行为n,m,接下来n行,每行包含k+1个数字,第一个为k,表示该集合的元素个数,接下来k行表示集合元素。
[align=left]Sample Input[/align]
4 4
1 1
1 2
1 3
1 4
2 4
3 1 2 3
4 1 2 3 4
[align=left]Sample Output[/align]
15
2
分析:以为m的规模很小,可以用二进制表示集合。借助位运算的或( | )来达到集合合并的目的。
比如一个集合中有两个元素 1 3 那就用5 (101)表示这个集合
比如一个集合(1 4 )和一个集合(1 2 3)进行合并 那就是 (9)1001 | 111(7)=1111 就是15
代码如下:
题目大意:给定n个集合,每个集合都是由大于等于1小于等于m的数字组成,m最大为14。由给出的集合可以组成多少个不同的集合。
输入描述:第一行为n,m,接下来n行,每行包含k+1个数字,第一个为k,表示该集合的元素个数,接下来k行表示集合元素。
[align=left]Sample Input[/align]
4 4
1 1
1 2
1 3
1 4
2 4
3 1 2 3
4 1 2 3 4
[align=left]Sample Output[/align]
15
2
分析:以为m的规模很小,可以用二进制表示集合。借助位运算的或( | )来达到集合合并的目的。
比如一个集合中有两个元素 1 3 那就用5 (101)表示这个集合
比如一个集合(1 4 )和一个集合(1 2 3)进行合并 那就是 (9)1001 | 111(7)=1111 就是15
代码如下:
# include<stdio.h> # include<string.h> int n,m,k; int dp[1<<15]; int main(){ int i; while(scanf("%d%d",&n,&m)!=EOF){ memset(dp,0,sizeof(dp)); while(n--){ scanf("%d",&k); int set = 0; int temp; for(i=1;i<=k;i++){ //得到这个集合的二进制表示 scanf("%d",&temp); set = set|(1<<(temp-1)); } dp[set] = 1; for(i=0; i<(1<<m); i++) //将新的集合与以往得到的集合合并 if(dp[i]) dp[i|set] = 1; } int ans = 0; for(i=0; i<(1<<m); i++) //判断可以组成集合的个数 if(dp[i]) ans++; printf("%d\n",ans); } return 0; }
相关文章推荐
- hdu 3006 The Number of set 状态压缩
- HDU 3006 The Number of set (状态压缩)
- HDU 3006 The Number of set (状态压缩dp)
- HDU 3006 The Number of set (状态压缩+hash)
- HDU 3006 The Number of set状态压缩
- hdu 3006 The Number of set 状态压缩
- hdu 3006 The Number of set 状态压缩
- HDU 3006 The Number of set (搜索+位压缩)
- HDU 3006 The Number of set -- 简单巧妙的位运算
- HDU 3006 The Number of set
- HDU 3006 The Number of set [位运算]
- HDU 3006 The Number of set
- hdu 3006 The Number of set
- hdu 3006 The Number of set
- HDU,3006,The Number of set
- [置顶]The Number of set-hdu-3006
- HDU ACM 3006 The Number of set (位运算)
- HDU 3006 The Number of set
- hdu 3006 The Number of set(位运算)
- HDU OJ 3306 The Number of set【状态压缩】