Written with StackEdit.

Description

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

Input

只有一行,其中有一个正整数 \(n\),\(30\%\)的数据满足 \(n\leq20\)。

Output

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

Sample Input

4

Sample Output

8

【样例解释】

有\(8\) 个集合满足要求,分别是\(\emptyset\),\(\{1\}\),\(\{1,4\}\),\(\{2\}\),\(\{2,3\}\),\(\{3\}\),\(\{3,4\}\),\(\{4\}\).

Solution

  • 神仙构造题.
  • 考虑构造这样的一个矩阵

\[\begin{pmatrix}
1 & 3 & 9 & 27 & ...\\
2 & 6 & 18 & 54 & ...\\
4 & 12 & 36 & 108 & ...\\
8 & 24 & 72 & 216 & ...\\
... & ... & ... & ... & ...\\
\end{pmatrix} \quad\]

  • 其中一个数是它上边那个数的\(2\)倍,左边那个数的\(3\)倍.
  • 原问题转化为从矩阵中选出一些互不相邻的数.
  • 那么这个矩阵中的数是呈指数级增长的,规模不会超过\(20\).
  • 使用经典状压\(dp\)处理,逐行考虑.
  • 另,对于每个尚未出现过的数,需以它为左上角建一个矩阵,这样各个构造出的矩阵互不相交,利用乘法原理统计答案.

左上角的数增大时,矩阵没有填入数字的部分也不断增大.手动\(memset\).

#include<bits/stdc++.h>
using namespace std;
typedef long long LoveLive;
inline int read()
{
int out=0,fh=1;
char jp=getchar();
while ((jp>'9'||jp<'0')&&jp!='-')
jp=getchar();
if (jp=='-')
{
fh=-1;
jp=getchar();
}
while (jp>='0'&&jp<='9')
{
out=out*10+jp-'0';
jp=getchar();
}
return out*fh;
}
const int P=1e9+1;
inline int add(int a,int b)
{
return (a + b) % P;
}
inline int mul(int a,int b)
{
return 1LL * a * b % P;
}
const int MAXN=1e5+10;
int n;
int vis[MAXN];
int Martix[20][20];
int limit[20];//第i行的边界
int ans=1;
int r,c;
int judge(int st)
{
int ls=0;
while(st)
{
int p=st&1;
if(p && ls)
return 0;
ls=p;
st>>=1;
}
return 1;
}
vector<int> G;
void Build_Martix(int x)
{
memset(Martix,-1,sizeof Martix);
r=0,c=0;
int p;
for(int i=1;i<20;++i)
{
p=i==1?x:Martix[i-1][1]*2;
if(p>n)
{
r=i-1;
break;
}
Martix[i][1]=p;
vis[p]=1;
for(int j=2;j<20;++j)
{
p=Martix[i][j-1]*3;
if(p>n)
{
c=max(c,j-1);
limit[i]=j-1;
break;
}
Martix[i][j]=p;
vis[p]=1;
}
}
G.clear();
int S=1<<c;
for(int i=0;i<S;++i)
if(judge(i))
G.push_back(i);
}
int f[20][1<<20];
inline int check(int x,int y)
{
return !(x&y);
}
int dfs(int k,int st)//填好了前k行,且第k行状态为st的方案数.
{
if(k==1)
return 1;
if(f[k][st]!=-1)
return f[k][st];
int &res=f[k][st];
res=0;
int S=(1<<limit[k-1])-1;
for(int v=0;v<G.size();++v)
{
int i=G[v];
if(i>S)
break;
if(check(i,st))
res=add(res,dfs(k-1,i));
}
return res;
}
void solve(int x)//以x为左上角构造矩阵的方案数
{
Build_Martix(x);
for(int i=1;i<=r+1;++i)
{
int S=1<<limit[i];
for(int j=0;j<S;++j)
f[i][j]=-1;
}
//memset(f,-1,sizeof f);
ans=mul(ans,dfs(r+1,0));
}
int main()
{
n=read();
for(int i=1;i<=n;++i)
if(!vis[i])
solve(i);
printf("%d\n",ans);
return 0;
}

bzoj 2734 集合选数的更多相关文章

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

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

  2. 2734: [HNOI2012]集合选数

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

  3. 【BZOJ-2732】集合选数 状压DP (思路题)

    2734: [HNOI2012]集合选数 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1070  Solved: 623[Submit][Statu ...

  4. 【BZOJ-2734】集合选数 状压DP (思路题)

    2734: [HNOI2012]集合选数 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1070  Solved: 623[Submit][Statu ...

  5. bzoj2734【HNOI2012】集合选数

    2734: [HNOI2012]集合选数 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 831  Solved: 487 [Submit][Stat ...

  6. 【BZOJ2734】【HNOI2012】集合选数(状态压缩,动态规划)

    [BZOJ2734][HNOI2012]集合选数(状态压缩,动态规划) 题面 Description <集合论与图论>这门课程有一道作业题,要求同学们求出{1, 2, 3, 4, 5}的所 ...

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

    BZOJ_2734_[HNOI2012]集合选数_构造+状压DP 题意:<集合论与图论>这门课程有一道作业题,要求同学们求出{1, 2, 3, 4, 5}的所有满足以 下条件的子集:若 x ...

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

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

  9. 状压DP之集合选数

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

随机推荐

  1. Android平台利用OpenCL框架实现并行开发初试

    http://www.cnblogs.com/lifan3a/articles/4607659.html 在我们熟知的桌面平台,GPU得到了极为广泛的应用,小到各种电子游戏,大到高性能计算,多核心.高 ...

  2. winform webbrowser禁用网页target=blank

    /// <summary> /// 屏蔽target=_blank 的弹出窗口 /// </summary> /// <param name="sender&q ...

  3. html4与html5的区别

    一.HTML5更加灵活,支持下列多种形式 1.标签名可以大写(不推荐) -<SpAN>这个HTML5也的认</SpAN> 2.属性双引号可选(推荐添加双引号) -<div ...

  4. 20145222黄亚奇《网络对抗》web安全基础实践

    web安全基础实践 实验后回答问题 (1)SQL注入攻击原理,如何防御 原理:指web应用程序对用户输入数据的合法性没有判断,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语 ...

  5. 20145235李涛《网络对抗》Exp5 MSF基础应用

    基础问答 用自己的话解释什么是exploit,payload,encode? exploit:相当于搬运工,把攻击代码传送到靶机中. payload:相当于shellcode. encode:相当于包 ...

  6. 20162326 齐力锋 2016-2017-2 《程序设计与数据结构》 MySort.java 实验博客

    实验代码学习编程中的问题及解决方法 代码运行成功截图 首次代码运行出现的问题截图 问题1:无法从静态上下文中引用非静态方法 问题1解决方法及思考: split方法是非静态方法,需要借助对象来调用.我查 ...

  7. Spring Boot 快速入门(Eclipse)

    步骤一:关于版本(前期工作) JDK 1.8 maven 3.5 配置环境变量: 步骤二:创建项目 首先新建个maven项目(SpringBoot 应用,本质上是一个Java 程序,其采用的风格是 m ...

  8. eclipse——JavaEE插件

    步骤如下 1.先看自己的eclipse版本 2.开始安装JavaEE插件 http://download.eclipse.org/releases/Photon 注意:这里后面红色的是博主eclips ...

  9. 一种根据value解释成枚举的有效方法

    有时候需要根据实际情况将某个值解释成一个枚举,而不是根据枚举的名称.如有时0是枚举Gender.MALE的值,1是枚举Gender.FEMALE的值:有时0.1又可以是另一个枚举的值,比如0表示Cer ...

  10. ZZ__知识点

    1. DLL_PROCESS_ATTACH.DLL_PROCESS_DETACH 打印出相关信息 发现,Java Project 项目中,DLL 在 System.loadLibrary(...) 载 ...