HDU - 3006 The Number of set(状态压缩位运算)

http://acm.hdu.edu.cn/showproblem.php?pid=3006

题意

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

分析

因为m最大为14位,那么可以把一个集合压缩成一个数,每个元素对应二进制的一个位。所有状态最大为(1<<m)。用个数组记录出现的状态,用map实测超时。

#include<iostream>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<cstdio>
#include<algorithm>
#include<map>
#include<set>
#include<bitset>
#define rep(i,e) for(int i=0;i<(e);i++)
#define rep1(i,e) for(int i=1;i<=(e);i++)
#define repx(i,x,e) for(int i=(x);i<=(e);i++)
#define X first
#define Y second
#define PB push_back
#define MP make_pair
#define mset(var,val) memset(var,val,sizeof(var))
#define scd(a) scanf("%d",&a)
#define scdd(a,b) scanf("%d%d",&a,&b)
#define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define pd(a) printf("%d\n",a)
#define scl(a) scanf("%lld",&a)
#define scll(a,b) scanf("%lld%lld",&a,&b)
#define sclll(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
#define IOS ios::sync_with_stdio(false);cin.tie(0)

using namespace std;
typedef long long ll;
template <class T>
void test(T a){cout<<a<<endl;}
template <class T,class T2>
void test(T a,T2 b){cout<<a<<" "<<b<<endl;}
template <class T,class T2,class T3>
void test(T a,T2 b,T3 c){cout<<a<<" "<<b<<" "<<c<<endl;}
const int N = 1e6+10;
//const int MAXN = 210;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3fll;
const ll mod = 1000000007;
int T;
void testcase(){
    printf("Case #%d: ",++T);
}
const int MAXN = 100+5;
const int MAXM = 5e5+5;
int ma[MAXM];
int main() {
#ifdef LOCAL
    freopen("in.txt","r",stdin);
#endif // LOCAL
    int n,m,x,y,value;
    while(~scdd(n,m)){
        mset(ma,0);
        int ans=0;
        for(int i=0;i<n;i++){
            scd(x);
            value=0;
            for(int j=0;j<x;j++){
                scd(y);
                value+=(1<<(y-1));
            }
            ma[value]=1;
            for(int j=1;j <= (1<<m) ;j++){
                if(ma[j]){
                    ma[j|value]=1;
                }
            }

        }

        for(int i=1;i<=(1<<m);i++) if(ma[i]) ans++;
        cout<<ans<<endl;
    }
    return 0;
}

 

posted @ 2018-07-08 23:17  litos  阅读(173)  评论(0编辑  收藏  举报