集合选数
集合选数
题目描述
《集合论与图论》这门课程有一道作业题,要求同学们求出{1, 2, 3, 4, 5}的所有满足以 下条件的子集:若x 在该子集中,则2x 和3x 不能在该子集中。同学们不喜欢这种具有枚举性 质的题目,于是把它变成了以下问题:对于任意一个正整数n≤100000,如何求出{1, 2,..., n} 的满足上述约束条件的子集的个数(只需输出对1,000,000,001 取模的结果),现在这个问题就 交给你了。
输入
输入文件input.txt 只有一行,其中有一个正整数n,30%的数据满足n≤20。
输出
输出文件output.txt 仅包含一个正整数,表示{1, 2,..., n}有多少个满足上述约束条件 的子集。
样例输入
4
样例输出
8
提示
【样例解释】
有8 个集合满足要求,分别是空集,{1},{1,4},{2},{2,3},{3},{3,4},{4}。
solution
神题,想不到
如果当前一个数为x,把x*2^p*3^q 都抓出来,当成一个集合
1x | 3x | 9x | 27x | 81x |
2x | 6x | 18x | . | . |
4x | 12x | . | . | . |
8x | . | . | . | . |
16x | . | . | . | . |
类似这样构出一个矩阵
不同的矩阵之间互不影响
那么我们肯定是要在矩阵中选若干个数,使得任意两列都不相邻
注意到列数少只有11 ,可以状压dp解决
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxn 100005
#define ll long long
#define mod 1000000001
using namespace std;
int n,flag[maxn],Max[22];
ll ans=0,a[20][20],f[20][maxn];
ll work(int k){
int M;
for(int i=0;i<19;i++){
int t=(k*(1<<i));
if(t>n){M=i;break;}
for(int j=0,now=1;j<19;j++,now*=3){
a[i][j]=t*now;
//cout<<i<<' '<<j<<' '<<a[i][j]<<endl;
if(a[i][j]>n)break;
}
}
for(int i=0;i<M;i++){
Max[i]=0;
for(int j=0;j<19;j++){
if(a[i][j]>n)break;
if(!flag[a[i][j]])flag[a[i][j]]=1;
Max[i]+=(1<<j);
}
}
for(int i=0;i<=M;i++)
for(int j=0;j<=Max[i];j++)f[i][j]=0;
for(int j=0;j<=Max[0];j++)if(!(j&(j<<1)))f[0][j]=1;
for(int l=0;l<M;l++){
for(int i=0;i<=Max[l];i++){
for(int j=0;j<=Max[l+1];j++){
if((!(i&j))&&!(j&(j<<1))){
f[l+1][j]=(f[l+1][j]+f[l][i])%mod;
}
}
}
}
return f[M][0];
}
int main()
{
cin>>n;
ans=1;
for(int i=1;i<=n;i++)if(!flag[i])ans=(ans*work(i))%mod;
cout<<ans<<endl;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构