zoukankan      html  css  js  c++  java
  • BZOJ2734:[HNOI2012]集合选数

    Description

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

    Input

     只有一行,其中有一个正整数 n,30%的数据满足 n≤20。 

    Output

     仅包含一个正整数,表示{1, 2,..., n}有多少个满足上述约束条件 的子集。 

    Sample Input

    4

    Sample Output

    8
    【样例解释】
    有8 个集合满足要求,分别是空集,{1},{1,4},{2},{2,3},{3},{3,4},{4}。
     
    题解:
    设x为一个不含2与3因子的数,则可以构造出一个这样的矩阵:
    x x*3 x*3^2 x*3^3 . . .
    2*x 2*x*3 2*x*3^2 2*x*3^3 . . .
    2^2*x 2^2*x*3  2^2*x*3^2 2^2*x*3^3 . . .
    2^3*x 2^3*x*3  2^3*x*3^2 2^3*x*3^3 . . .
    . . . . . . .
    . . . . . . .
    . . . . . . .
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    例如x=1时:
     1   3   9  27 . . .
       2       6       18       54    . . .
       4       12       36       108    . . .
    8 24 72 216 . . .
    . . . . . . .
    . . . . . . .
    . . . . . . .
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    如此一来,不能同时取的数对在矩阵中一定是左右或是上下相邻的。因为n<=1000000,所以矩阵最多有11列,可以将每一行进行状态压缩DP。
    每个数一定且只存在于一个矩阵之中,两个矩阵之间没有关联,所以DP出每个矩阵的可行方案数,最后相乘就可以了。
     
    代码:
     1 const
     2   mo=1000000001;
     3 var
     4   i,j,k,l,n,m:longint;
     5   a:array[0..20,0..20]of longint;
     6   b:array[0..20]of longint;
     7   f:array[0..20,0..2048]of longint;
     8   bo:array[0..100005]of longint;
     9   bin:array[0..20]of longint;
    10   ans:int64;
    11 function qq(x:longint):longint;
    12 var i,j,y:longint;
    13 begin
    14   fillchar(b,sizeof(b),0);
    15   a[1,1]:=x;
    16   for i:=2 to 18 do
    17   if a[i-1,1]*2<=n then a[i,1]:=a[i-1,1]*2 else a[i,1]:=n+1;
    18   for i:=1 to 18 do
    19   for j:=2 to 11 do
    20   if a[i,j-1]*3<=n then a[i,j]:=a[i,j-1]*3 else a[i,j]:=n+1;
    21   for i:=1 to 18 do
    22   for j:=1 to 11 do
    23   if a[i,j]<=n then
    24   begin
    25     b[i]:=b[i]+bin[j-1];
    26     bo[a[i,j]]:=1;
    27   end;
    28   for i:=0 to 18 do
    29   for j:=0 to b[i] do f[i,j]:=0;
    30   f[0,0]:=1;
    31   for i:=0 to 17 do
    32   for j:=0 to b[i] do
    33   if f[i,j]>0 then
    34   for y:=0 to b[i+1] do
    35   if(j and y=0)and(y and(y shr 1)=0)then f[i+1,y]:=(f[i+1,y]+f[i,j])mod mo;
    36   exit(f[18,0]);
    37 end;
    38 begin
    39   bin[0]:=1;
    40   for i:=1 to 20 do bin[i]:=bin[i-1]shl 1;
    41   readln(n); ans:=1;
    42   for i:=1 to n do
    43   if bo[i]=0 then ans:=(ans*qq(i))mod mo;
    44   writeln(ans);
    45 end.
    View Code
     
  • 相关阅读:
    opencv 遍历Mat对象中数据方法-转
    JVM OutOfMemoryError 分析
    hibernate validation HV000030: No validator could be found for constraint
    通过aop实现rpc统一参数校验&异常捕捉
    java8 lambda groupingby 分组保持原来顺序
    递归判断素组是否有序
    dubbo 直连
    Linux 删除openjdk
    telnet命令调用远程dubbo 接口
    git submodule ssh key
  • 原文地址:https://www.cnblogs.com/GhostReach/p/6290821.html
Copyright © 2011-2022 走看看