hdu 3006 枚举集合能够产生的全部并集的集合

http://acm.hdu.edu.cn/showproblem.php?

pid=3006

刚买的CHERRY键盘 手感真好 可惜不习惯 写代码老是打错。一个题写了一上午,都是各种按错键DEBUG.....

開始想的是DFS  发现好像不行

然后想的是两重循环能够枚举全部的2个集合的并集。3重循环能够枚举全部3个集合的并集,那么n个子集貌似须要n重循环。NP问题啊,,。。。

做法还是从小的数去模拟,由于仅仅有14个。所以状压存储

如第一个样例

四个子集1,2,3,4

二进制0001 0010 0011 0100

第一个与其它三个或操作  得到0001 0010 0011 0100 0011  0101....

然后第二个数和新的数异或

代码中第二重循环 i+1開始,放反复,事实上省不了多少时间 o(╯□╰)o

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <queue>
using namespace std;

#define IN(s) freopen(s,"r",stdin)
#define CL(a,b) memset(a,b,sizeof(a))

const int MAXN = 1<<15;
int vis[MAXN],ans[MAXN];

int main()
{
    //IN("hdu3006.txt");
    int n,m;
    int k;
    while(~scanf("%d%d",&n,&m))
    {
        CL(vis,0);
        int cnt=0;
        for(int j=0;j<n;j++)
        {
            scanf("%d",&k);
            int t=0,a=0;
            for(int i=0;i<k;i++)
            {
                scanf("%d",&t);
                a|=1<<(t-1);
            }
            if(!vis[a])
            {
                vis[a]=1;
                ans[cnt++]=a;
            }
        }

        int ct=cnt;
        for(int i=0;i<ct;i++)
        {
            int s=ans[i];
            for(int j=i+1;j<cnt;j++)
            {
                if(!vis[(s|ans[j])] && i!=j)
                {
                    vis[s|ans[j]]=1;
                    ans[cnt++]=s|ans[j];
                }
            }
        }
        printf("%d\n",cnt);
    }
    return 0;
}
时间: 2024-10-27 17:29:25

hdu 3006 枚举集合能够产生的全部并集的集合的相关文章

hdu 3006 枚举集合可以产生的所有并集的集合

http://acm.hdu.edu.cn/showproblem.php?pid=3006 刚买的CHERRY键盘 手感真好 可惜不习惯 写代码老是打错,一个题写了一上午,都是各种按错键DEBUG..... 开始想的是DFS  发现好像不行 然后想的是两重循环可以枚举所有的2个集合的并集,3重循环可以枚举所有3个集合的并集,那么n个子集貌似需要n重循环,NP问题啊,,,,, 做法还是从小的数去模拟,因为只有14个,所以状压存储 如第一个例子 四个子集1,2,3,4 二进制0001 0010 0

hdu 3006 The Number of set(思维+壮压DP)

The Number of set Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1056    Accepted Submission(s): 655 Problem Description Given you n sets.All positive integers in sets are not less than 1 and

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<cst

集合详解(五):集合嵌套与Collections工具类

一.集合嵌套 1.HashMap嵌套HashMap <span style="font-size:18px;"> /* * HashMap嵌套HashMap * * 传智播客 * jc 基础班 * 陈玉楼 20 * 高跃 22 * jy 就业班 * 李杰 21 * 曹石磊 23 * * 先存储元素,然后遍历元素 */ public void test3(){ // 创建集合对象 HashMap<String, HashMap<String, Integer>

UNION(并集)集合运算

在集合论中,两个集合(记为集合A和B)的并集是一个包含集合A和B中所有元素的集合.换句话说,如果一个元素属于任何一个输入集合,那么它也属于结果集. 在T-SQL中,UNION 集合运算可以将两个输入查询的结果集组合成一个结果集.如果一个行在任何一个输入集合中出现,它也会在UNION运算的结果中出现.T-SQL 支持在UNION集合运算中使用UNION ALL 和UNION(隐含DISTINCT,DISTINCT不能显示指定)选项. UNION ALL 集合运算 对于作为运算的输入查询而生成的多集

Python 集合set()添加删除、交集、并集、集合操作详解

在Python set是基本数据类型的一种集合类型,它有可变集合(set())和不可变集合(frozenset)两种.创建集合set.集合set添加.集合删除.交集.并集.差集的操作都是非常实用的方法. 创建集合set python set类是在python的sets模块中,大家现在使用的python2.7.x中,不需要导入sets模块可以直接创建集合.>>>set('boy')set(['y', 'b', 'o']) 集合添加.删除 python 集合的添加有两种常用方法,分别是add

Python 集合set添加删除、交集、并集、集合操作符号

在Python中集合set是基本数据类型的一种,它有可变集合(set)和不可变集合(frozenset)两种.创建集合set.集合set添加.集合删除.交集.并集.差集的操作都是非常实用的方法. 1.创建集合 set类是在python的sets模块中,大家现在使用的python2.3中,不需要导入sets模块可以直接创建集合.>>>set('boy')set(['y', 'b', 'o']) 2.集合添加.删除 集合的添加有两种常用方法,分别是add和update.集合add方法:是把要

Java基础——集合(二)——迭代器、Map集合

接上篇,<Java基础--集合(一)--集合体系和Collection> 四.迭代器的使用 使用步骤: 1.通过集合对象获取迭代器对象. 2.通过迭代器对象判断. 3.通过迭代器对象获取. 迭代器原理 由于多种集合的数据结构不同,所以存储方式不同,所以,取出方式也不同. 这个时候,我们就把判断和获取功能定义在了一个接口中,将来,遍历哪种集合的时候,只要该集合内部实现这个接口即可. 迭代器源码 public interface Iterator { publicabstract boolean

Collection集合的总结以及如果选择适合的集合(包括对List和Set的对比)

1:Collection的关系图 2:Set集合(理解) (1)Set集合的特点 无序,唯一 (2)HashSet集合(掌握) A:底层数据结构是哈希表(是一个元素为链表的数组) B:哈希表底层依赖两个方法:hashCode()和equals() 执行顺序: 首先比较哈希值是否相同 相同:继续执行equals()方法 返回true:元素重复了,不添加 返回false:直接把元素添加到集合 不同:就直接把元素添加到集合 C:如何保证元素唯一性的呢? 由hashCode()和equals()保证的,