zoukankan      html  css  js  c++  java
  • hdu3006 状态压缩+位运算+hash(小想法题)

    题意:
           给了n个集合,问你这n个集合可以组合出多少种集合,可以自己,也可以两个,也可以三个....也可以n个集合组在一起。


    思路:

          是个小想法题目,要用到二进制压缩,位运算,还有hash,这4样加起来说明这个题目真的很不错,不废话,首先对于每个集合有k个元素,每个元素都是不大于14的,那么我们可以二进制压缩,把每个集合压缩成一个二进制数,压缩过程设计到位运算对于每个集合
    tmp = 0;
    for(i ,1 - k) scanf(num) ,tmp = tmp | (1 << (num - 1));
    hash[tmp] = 1;标记上当前的这个集合是可以得到的。
    这样最后的这个tmp就是当前的这个集合压缩后的数,然后我们在枚举之前的所有可能状态,得到新的可能状态(其实就是简单dp)

    for(i = 1 ;i < 1 << 14 ;i ++) if(hash[i]) hash[i|tmp] = 1; 之前的可能情况加上当

    前的可能情况也是可能情况。最后在统计下可能情况的个数就ok了,
    for(i = 1 ;i < 1 << 14 ;i ++) if(hash[i]) ans++;

    做这个题目的时候sb了,开了个 hash[1<<13+1] 哎! 1<<13+1 != 1 << 14 - 1.


    #include<stdio.h>
    #include<string.h>
    
    int hash[1 << 14];
    
    int main ()
    {
       int n ,m ,i ,j ,k ,num ,tmp ,ans;
       while(~scanf("%d %d" ,&n ,&m))
       {
          memset(hash ,0 ,sizeof(hash));
          for(i = 1 ;i <= n ;i ++)
          {
             scanf("%d" ,&k);
             tmp = 0;
             for(j = 1 ;j <= k ;j ++)
             scanf("%d" ,&num) ,tmp = tmp | (1 << (num - 1));
             hash[tmp] = 1;
             for(j = 0 ;j < 1 << 14 ;j ++)
             if(hash[j]) hash[tmp | j] = 1;
          }
          ans = 0;
          for(i = 0 ;i < 1 << 14 ;i ++)
          if(hash[i]) ans ++;
          printf("%d
    " ,ans);
       }
       return 0;
    } 
          
    
    
    
    

  • 相关阅读:
    docker入门——centos安装
    NET应用——你的数据安全有必要升级
    mysql事件机制——定时任务
    是时候升级你的Js工具了-分页【基于JQ】
    优美库图片系统
    爬虫之蜂鸟网图片爬取
    壁纸提取
    CSDN刷阅读数
    tkinter基础-输入框、文本框
    数据结构与算法之选择排序
  • 原文地址:https://www.cnblogs.com/csnd/p/12062970.html
Copyright © 2011-2022 走看看