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
     
  • 相关阅读:
    Android 主题theme说明 摘记
    Android开发 去掉标题栏方法 摘记
    安卓项目五子棋代码详解(二)
    关于 ake sure class name exists, is public, and has an empty constructor that is public
    百度地图3.0实现图文并茂的覆盖物
    android onSaveInstanceState()及其配对方法。
    关于集成科大讯飞语音识别的 一个问题总结
    android 关于 webview 控制其它view的显示 以及更改view数据失败的问题总结
    C# 解析 json Newtonsoft果然强大,代码写的真好
    c#数据类型 与sql的对应关系 以及 取值范围
  • 原文地址:https://www.cnblogs.com/GhostReach/p/6290821.html
Copyright © 2011-2022 走看看