zoukankan      html  css  js  c++  java
  • HDU 3006 The Number of set(位运算 状态压缩)

    题目链接http://acm.hdu.edu.cn/showproblem.php?pid=3006

    题目大意:给定n个集合,每个集合都是由大于等于1小于等于m的数字组成,m最大为14。由给出的集合可以组成多少个不同的集合。

    输入描述:第一行为n,m,接下来n行,每行包含k+1个数字,第一个为k,表示该集合的元素个数,接下来k行表示集合元素。

    Sample Input
    4 4
    1 1
    1 2
    1 3
    1 4
    2 4
    3 1 2 3
    4 1 2 3 4
     
    Sample Output
    15
    2
     
    分析:以为m的规模很小,可以用二进制表示集合。借助位运算的或( | )来达到集合合并的目的。
       比如一个集合中有两个元素   1  3   那就用5 (101)表示这个集合
      比如一个集合(1 4 )和一个集合(1 2 3)进行合并 那就是  (9)1001 | 111(7)=1111  就是15 
     
    代码如下:
     1 # include<stdio.h>
     2 # include<string.h>
     3 int n,m,k;
     4 int dp[1<<15];
     5 int main(){
     6     int i;
     7     while(scanf("%d%d",&n,&m)!=EOF){
     8         memset(dp,0,sizeof(dp));
     9         while(n--){
    10             scanf("%d",&k);
    11             int set = 0;
    12             int temp;
    13             for(i=1;i<=k;i++){    //得到这个集合的二进制表示
    14                 scanf("%d",&temp);
    15                 set = set|(1<<(temp-1));
    16             }
    17             
    18             dp[set] = 1;
    19             for(i=0; i<(1<<m); i++)    //将新的集合与以往得到的集合合并
    20                 if(dp[i])
    21                     dp[i|set] = 1;
    22         }
    23         int ans = 0;
    24         for(i=0; i<(1<<m); i++)    //判断可以组成集合的个数
    25             if(dp[i])
    26                 ans++;
    27             printf("%d
    ",ans);
    28     }
    29     return 0;
    30 }
  • 相关阅读:
    启发式搜索学习~~
    bzoj1032
    bzoj1037
    bzoj1029
    codevs1081 线段树练习 2
    bzoj1006
    bzoj1003
    Codeforces 607B Zuma
    20155326《网络对抗》网络欺诈技术防范
    20155326刘美岑 Exp6 信息收集与漏洞扫描
  • 原文地址:https://www.cnblogs.com/acm-bingzi/p/3283315.html
Copyright © 2011-2022 走看看