BZOJ_2734_[HNOI2012]集合选数_构造+状压DP

题意:《集合论与图论》这门课程有一道作业题,要求同学们求出{1, 2, 3, 4, 5}的所有满足以 下条件的子集:若 x 在该子集中,则 2x 和 3x 不能在该子集中。同学们不喜欢这种具有枚举性 质的题目,于是把它变成了以下问题:对于任意一个正整数 n≤100000,如何求出{1, 2,..., n} 的满足上述约束条件的子集的个数(只需输出对 1,000,000,001 取模的结果),现在这个问题就 交给你了。

分析:

我们构造出一个矩阵

$\begin{matrix}
    1&2^03^1&2^03^2\\
    2^13^0&2^13^1&2^13^2\\
    2^23^0&2^23^1&2^23^2\\
\end{matrix}
$

发现矩阵的相邻两个格子的数不能同时取

状压DP一下

要把所有不在矩阵中的数当作1重新构造,比如5,7等等

每个矩阵的结果乘起来就是答案

代码:

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <algorithm>
  4. using namespace std;
  5. #define LL long long
  6. LL p=1000000001,A,f[18][1<<12];
  7. int vis[100050],s[18],mat[18][18];
  8. LL ans=1;
  9. void build(int x){
  10. int n=1,m=1,now=x;
  11. while(now*3<=A)m++,now*=3;
  12. now=x;
  13. while(now*2<=A)n++,now<<=1;
  14. int mask=(1<<m)-1;
  15. memset(s,0,sizeof(s));
  16. memset(f,0,sizeof(f));
  17. memset(mat,0,sizeof(mat));
  18. mat[1][1]=x;vis[x]=1;
  19. for(int i=2;i<=m;i++){
  20. mat[1][i]=mat[1][i-1]*3;
  21. vis[mat[1][i]]=1;
  22. }
  23. s[1]=mask;
  24. for(int i=2;i<=n;i++){
  25. mat[i][1]=mat[i-1][1]*2;
  26. vis[mat[i][1]]=1;
  27. for(int j=2;j<=m;j++){
  28. mat[i][j]=mat[i-1][j]*2;
  29. if(mat[i][j]>A){
  30. s[i]=mask^((1<<m-j+1)-1);
  31. break;
  32. }
  33. vis[mat[i][j]]=1;
  34. }
  35. if(!s[i])s[i]=mask;
  36. }
  37. f[0][0]=1;
  38. s[0]=mask;
  39. for(int i=0;i<n;i++){
  40. for(int j=0;j<=mask;j++){
  41. if((j|s[i])!=s[i])continue;
  42. if(j&(j<<1))continue;
  43. for(int k=0;k<=mask;k++){
  44. if((k|s[i+1])!=s[i+1])continue;
  45. if(k&(k<<1))continue;
  46. if(j&k)continue;
  47. f[i+1][k]+=f[i][j];
  48. f[i+1][k]%=p;
  49. }
  50. }
  51. }
  52. LL re=0;
  53. for(int i=0;i<=mask;i++)re+=f[n][i],re%=p;
  54. ans=re*ans%p;
  55.  
  56. /*for(int i=1;i<=n;i++){
  57. for(int j=1;j<=m;j++){
  58. printf("%d ",mat[i][j]);
  59. }
  60. puts("");
  61. }*/
  62.  
  63. /*for(int i=1;i<=n;i++){
  64. printf("%d\n",s[i]);
  65. }*/
  66. }
  67. int main(){
  68. scanf("%lld",&A);
  69. for(int i=1;i<=A;i++){
  70. if(!vis[i])build(i);
  71. }
  72. printf("%lld",ans);
  73. }

BZOJ_2734_[HNOI2012]集合选数_构造+状压DP的更多相关文章

  1. [HNOI2012]集合选数(构造,状态压缩,DP)

    神仙题. 莫名其妙的就试一试把所有数放进一个类似矩阵的东西里面. 首先把 \(1\) 放到左上角,然后在每个数的右边放它的 \(3\) 倍(大于 \(n\) 就不用放了),下面放它的 \(2\) 倍( ...

  2. [HNOI2012]集合选数 --- 状压DP

    [HNOI2012]集合选数 题目描述 <集合论与图论>这门课程有一道作业题,要求同学们求出\({1,2,3,4,5}\)的所有满足以 下条件的子集:若 x 在该子集中,则 2x 和 3x ...

  3. bzoj 2734: [HNOI2012]集合选数 状压DP

    2734: [HNOI2012]集合选数 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 560  Solved: 321[Submit][Status ...

  4. $HNOI2012\ $ 集合选数 状压$dp$

    \(Des\) 求对于正整数\(n\leq 1e5\),{\(1,2,3,...,n\)}的满足约束条件:"若\(x\)在该子集中,则\(2x\)和\(3x\)不在该子集中."的子 ...

  5. 洛谷$P3226\ [HNOI2012]$集合选数 状压$dp$

    正解:$dp$ 解题报告: 传送门$QwQ$ 考虑列一个横坐标为比值为2的等比数列,纵坐标为比值为3的等比数列的表格.发现每个数要选就等价于它的上下左右不能选. 于是就是个状压$dp$板子了$QwQ$ ...

  6. 2734: [HNOI2012]集合选数

    2734: [HNOI2012]集合选数 链接 分析: 转化一下题意. 1 3 9 27... 2 6 18 54... 4 12 36 108... 8 24 72 216... ... 写成这样的 ...

  7. 2734: [HNOI2012]集合选数 - BZOJ

    Description <集合论与图论>这门课程有一道作业题,要求同学们求出{1, 2, 3, 4, 5}的所有满足以 下条件的子集:若 x 在该子集中,则 2x 和 3x 不能在该子集中 ...

  8. [HNOI2012]集合选数(状压DP+构造)

    题目要求若出现x,则不能出现2x,3x 所以我们考虑构造一个矩阵 \(1\ 2\ 4 \ 8--\) \(3\ 6\ 12\ 24--\) \(9\ 18\ 36--\) \(--\) 不难发现,对于 ...

  9. BZOJ 2734: [HNOI2012]集合选数 [DP 状压 转化]

    传送门 题意:对于任意一个正整数 n≤100000,如何求出{1, 2,..., n} 的满足若 x 在该子集中,则 2x 和 3x 不能在该子集中的子集的个数(只需输出对 1,000,000,001 ...

随机推荐

  1. intersection of two linked lists.(两个链表交叉的地方)

    Write a program to find the node at which the intersection of two singly linked lists begins. For ex ...

  2. Java内存模型与指令重排

    Java内存模型与指令重排 本文暂不讲JMM(Java Memory Model)中的主存, 工作内存以及数据如何在其中流转等等, 这些本身还牵扯到硬件内存架构, 直接上手容易绕晕, 先从以下几个点探 ...

  3. Collections模块下的Counter

    class Counter(dict) 这个类是dict的子类,对哈希类型的项进行计数,元素被存储为字典的键,他们的计数将作为字典的键值. 主要介绍两个方法: 1.初始化方法:__init__(*ar ...

  4. tomcat启动非常慢;连接oracle数据库失败,jdbc错误日志提示connection reset;测试主机间网络互通及数据库端口都正常

      [判断确认:这时候大家可能要去检查一下/dev/random 这个设备档案.可以用cat /dev/random 来看它的内容,如果你发现他一直没显示任何内容﹝可能是乱码数字之类的﹞,那就是它出问 ...

  5. Failed building wheel for scandir 解决方案

    unbuntu 16.04 运行 pip install jupyter --upgrade 的时候出现了下面的错误 Failed building wheel for scandir Running ...

  6. Coursera-AndrewNg(吴恩达)机器学习笔记——第二周

    一.多变量线性回归问题(linear regression with multiple variables) 搭建环境OctaveWindows的安装包可由此链接获取:https://ftp.gnu. ...

  7. win8系统下,python 2.7安装xlrd,xlutils和xlwt的方法

    一.先到python的官网上下载压缩包 二.将压缩包解压 三.将打开cmd,进入到解压文件所在的位置 四.键入 python setup.py install

  8. php使用http_build_query,parse_url,parse_str创建与解析url详解

    1.http_build_query string http_build_query ( mixed $query_data [, string $numeric_prefix [, string $ ...

  9. HTML 返回顶部

    每次看淘宝,看微信,都回有回到顶部的小logo,小图标,或者双击返回顶部.所以就学习了如何返回顶部的操作,一开始是联想html中的链接描点,在开头出设置个标签,下面点击另外一个标志回去.有三种觉得比较 ...

  10. springboot: thymeleaf 使用详解

    springboot:thymeleaf,这篇文章将更加全面详细的介绍thymeleaf的使用.thymeleaf 是新一代的模板引擎,在spring4.0中推荐使用thymeleaf来做前端模版引擎 ...