首页 > 代码库 > BZOJ2734: [HNOI2012]集合选数
BZOJ2734: [HNOI2012]集合选数
2734: [HNOI2012]集合选数
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 505 Solved: 287
[Submit][Status]
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}。
【样例解释】
有8 个集合满足要求,分别是空集,{1},{1,4},{2},{2,3},{3},{3,4},{4}。
HINT
Source
day2
题解:
不能再神的做法。。。
1 3 9
2 6 18
。。。。
然后就转化成了不能选两个相邻的数的方案数了。。。状压搞定
代码:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 #include<iostream> 7 #include<vector> 8 #include<map> 9 #include<set>10 #include<queue>11 #include<string>12 #define inf 100000000013 #define maxn 100000+10014 #define maxm 500+10015 #define eps 1e-1016 #define ll long long17 #define pa pair<int,int>18 #define mod 100000000119 using namespace std;20 inline int read()21 {22 int x=0,f=1;char ch=getchar();23 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}24 while(ch>=‘0‘&&ch<=‘9‘){x=10*x+ch-‘0‘;ch=getchar();}25 return x*f;26 }27 int n,num[20];28 ll f[20][1<<12];29 bool v[maxn];30 ll get(int x)31 {32 int m=0;33 memset(num,0,sizeof(num));34 memset(f,0,sizeof(f));35 f[0][0]=1;36 while(x<=n)37 {38 m++;39 int xx=x;40 while(xx<=n)41 {42 num[m]++;v[xx]=1;xx*=3;43 }44 for(int i=0;i<1<<num[m];i++)45 {46 int j;47 for(j=1;j<num[m];j++)if((i&(1<<(j-1)))&&(i&(1<<j)))break; 48 if(j!=num[m])continue;49 for(j=0;j<1<<num[m-1];j++)if(!(i&j))f[m][i]=(f[m][i]+f[m-1][j])%mod;50 }51 x*=2;52 }53 ll t=0;54 for(int i=0;i<1<<num[m];i++)t=(t+f[m][i])%mod;55 return t;56 }57 int main()58 {59 freopen("input.txt","r",stdin);60 freopen("output.txt","w",stdout);61 n=read();62 ll ans=1;63 for(int i=1;i<=n;i++)if(!v[i])ans=(ans*get(i))%mod;64 printf("%lld\n",ans);65 return 0;66 }
UPD:我说我的程序怎么跑得贼慢。。。就因为我每次就memset吗?。。。
还有一个就是判断 i 中是否有两个连续的1,只要判断 i&(i<<1)是否为0即可
BZOJ2734: [HNOI2012]集合选数
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。