HDU 3006 The Number of set

转自: http://zc634579757.blog.163.com/blog/static/1244974622009716104841721/

这题真是让我看到了位运算和状压DP的神奇之处!

 这题就是用一个二进制数保存一个集合的元素 比如一个集合中有两个元素   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<stdio.h>
#include<string.h>
int s[1<<15];
int
n,m,k,element;
int
main()
{

    while
(scanf("%d%d",&n,&m)!=EOF)
    {

        int
ans=0;
        memset(s,0,sizeof(s));
        while
(n--)
        {

            int
set=0;
            scanf("%d",&k);
            while
(k--)
            {

                scanf("%d",&element);
                set=set|(1<<(element-1));
            }

            s[set]=1;
            for
(int j=0;j<=(1<<14);j++)
            {

                if
(s[j]){s[set|j]=1;}
            }
        }


        for
(int i=0;i<=1<<14;i++)
        {

            if
(s[i]){ans++;}
        }

        printf("%d\n",ans);
    }

    return
0;
}

posted on 2011-05-27 18:02  lonelycatcher  阅读(683)  评论(2编辑  收藏  举报

导航