集合的划分(2)

/*=======================================================================
3253:集合的划分
总时间限制: 1000ms 内存限制: 65536kB
描述
把一个集A(本题中的集合均不含重复元素)分成若干个非空子集,使得A中每个元素属于
且仅属于一个子集,那么这些子集构成的集合称为A的一个划分。
比如A={1,2,3},那么{ {1},{2 ,3} }以及{ {1},{2},{3} } 都是A的划分。
现在给定一个整数n,我们希望知道包含n个元素的集合有多少不同的划分。
当n=3的时候,仍然考虑集合{1,2,3},它的所有划分如下
{ {1} , {2} , {3} }
{ {1 , 2} , {3} }
{ {1 , 3} , {2} }
{ {1} , {2 , 3} }
{ {1 , 2 , 3} }
只有5种,但随n的增加,划分方法的个数会以指数速度增加。
比如n=4的时候,就有15种方法,考虑集合{1,2,3,4},划分方式如下
{ {1},{2},{3},{4}}
{{1},{2},{3,4}}
{{1,2},{3},{4}}
{{1,3},{2},{4}}
{{1,4},{2},{3}}
{{1},{2,3},{4}}
{{1},{3},{2,4}}
{{1,2},{3,4}}
{{1,3},{2,4}}
{{1,4},{2,3}}
{{1},{2,3,4}}
{{2},{1,3,4}}
{{3},{1,2,4}}
{{4},{1,2,3}}
{{1,2,3,4}}
当n>15的时候,划分方法数将超过32位整数所能表示的范围,我们希望你的程序能计算出
n<=15的时候,包含n个元素的集合的划分方法的个数
输入
一个整数n(0<=n<=15,n=0的时候认为有一种划分方法)
输出
包含n个不同元素的集合的划分方法的个数
样例输入
3
15
样例输出
5
1382958545

提示
递归公式,
设n个元素的集合可以划分为F(n,m)个不同的由m个非空子集组成的集合。
F(n,m) = 1, where n=0, n=m, n=1, or m=1
F(n,m) = 0, where n<m
否则
F(n,m)=F(n-1,m-1)+m*F(n-1,m)

例如:
考虑3个元素的集合,可划分为
① 1个子集的集合:{{1,2,3}}
② 2个子集的集合:{{1,2},{3}},{{1,3},{2}},{{2,3},{1}}
③ 3个子集的集合:{{1},{2},{3}}
∴F(3,1)=1;F(3,2)=3;F(3,3)=1;

如果要求F(4,2)该怎么办呢?

A.往①里添一个元素{4},得到{{1,2,3},{4}}

B.往②里的任意一个子集添一个4,得到
{{1,2,4},{3}},{{1,2},{3,4}},
{{1,3,4},{2}},{{1,3},{2,4}},
{{2,3,4},{1}},{{2,3},{1,4}}

∴F(4,2)=F(3,1)+2*F(3,2)=1+2*3=7

来源:http://bailian.openjudge.cn/practice/3253/
=========================================================================*/
 1 #include <stdio.h>
 2 long long fun(int n,int m)
 3 {
 4     if(n<m) return 0;
 5     else if(n==0||n==m||n==1||m==1) return 1;
 6     else return fun(n-1,m-1)+m*fun(n-1,m);
 7 }
 8 int main(int argc, char *argv[])
 9 {
10     int n,i;
11     long long ans;
12     while(scanf("%d",&n)!=EOF)
13     {
14         ans=0;
15         if(n==0) ans=1;
16         for(i=1;i<=n;i++)
17         {
18             ans=ans+fun(n,i);
19         }
20         printf("%lld\n",ans);
21     }
22     return 0;
23 }

题目链接:http://bailian.openjudge.cn/practice/3253/

时间: 2024-10-12 02:12:27

集合的划分(2)的相关文章

【递归与递推】集合的划分

[递归与递推]集合的划分 题目描述 设s是一个具有n个元素的集合,s={a1,a2,……,an},现将s划分成k个满足下列条件的子集合s1,s2,……,sk,且满足:(1)si≠∅(2)si∩sj=∅(3)s1∪s2∪s3∪...∪sk=s则称s1,s2,...,sk是集合s的一个划分.它相当于把s集合中的n个元素a1,a2,...,an放入k个(0<k≤n<30)无标号的盒子中,使得没有一个盒子为空.请你确定n个元素a1,a2,...,an放入k个无标号盒子中去的划分数s(n,k). 输入

集合的划分

题目描述 Description 设S是一个具有n个元素的集合,S={a1,a2,……,an},现将S划分成k个满足下列条件的子集合S1,S2,……,Sk ,且满足: 则称S1,S2,……,Sk是集合S的一个划分.它相当于把S集合中的n个元素a1 ,a2,……,an 放入k个(0<k≤n<30=无标号的盒子中,使得没有一个盒子为空.请你确定n个元素a1 ,a2 ,……,an 放入k个无标号盒子中去的划分数S(n,k) 输入输出格式 Input/output 输入格式:一个正整数K.输出格式:一

1315:【例4.5】集合的划分

题目连接:http://ybt.ssoier.cn:8088/problem_show.php?pid=1315 1 #include<iostream> 2 using namespace std; 3 int s(int n, int k) 4 { 5 if(k>n || k==0)return 0; 6 if(k==n || k==1)return 1; 7 return s(n-1, k-1)+k*s(n-1, k); 8 } 9 int main() 10 { 11 int n

递归例题4.5集合的划分

[题目描述] 设S是一个具有n个元素的集合,S=?a1,a2,……,an?,现将S划分成k个满足下列条件的子集合S1,S2,……,Sk,且满足: 1.Si≠∅ 2.Si∩Sj=∅           (1≤i,j≤k,i≠j) 3.S1∪S2∪S3∪…∪Sk=S 则称S1,S2,……,Sk是集合S的一个划分.它相当于把S集合中的n个元素a1,a2,……,an 放入k个(0<k≤n<30)无标号的盒子中,使得没有一个盒子为空.请你确定n个元素a1,a2,……,an 放入kk个无标号盒子中去的划分

拆分集合为相等的子集合(第1届第1题)

题目要求 问题描述:将1到N的连续整数组成的集合划分为两个子集合,且保证每个集合的数字和相等.例如,对于N=4,对应的集合{1,2,3,4},能被划分为{1,4}.{2,3}两个集合,使得1+4=2+3,且划分方案只有此一种.编程实现给定任一正整数N(1<=N<=39),输出其符合题意的划分方案数. 样例输入1:3 样例输出1:1    (可划分为{1,2}.{3}) 样例输入2:4 样例输出2:1    (可划分为{1,3}.{2,4}) 样例输入3:7 样例输出3:4    (可划分为{1

离散数学--4.4 等价关系与偏序关系

• 4.4.1 等价关系• 4.4.2 等价类和商集• 4.4.3 集合的划分• 4.4.4 偏序关系• 4.4.5 偏序集与哈斯图

Bell(hdu4767+矩阵+中国剩余定理+bell数+Stirling数+欧几里德)

Bell Time Limit:3000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 4767 Description What? MMM is learning Combinatorics!? Looks like she is playing with the bell sequence now: bell[n] = number of ways to part

贝尔数(来自维基百科)&amp; Stirling数

贝尔数 贝尔数以埃里克·坦普尔·贝尔(Eric Temple Bell)为名,是组合数学中的一组整数数列,开首是(OEIS的A000110数列): Bell Number Bn是基数为n的集合的划分方法的数目.集合S的一个划分是定义为S的两两不相交的非空子集的族,它们的并是S.例如B3 = 5因为3个元素的集合{a, b, c}有5种不同的划分方法: {{a}, {b}, {c}} {{a}, {b, c}} {{b}, {a, c}} {{c}, {a, b}} {{a, b, c}}; B0

BZOJ 1016: [JSOI2008]最小生成树计数

http://www.lydsy.com/JudgeOnline/problem.php?id=1016 题意: 思路: 一个无向图所有的最小生成树中某种权值的边的数目均相同. 引用一篇大牛的证明: 我们证明以下定理:一个无向图所有的最小生成树中某种权值的边的数目均相同. 开始时,每个点单独构成一个集合. 首先只考虑权值最小的边,将它们全部添加进图中,并去掉环,由于是全部尝试添加,那么只要是用这种权值的边能够连通的点,最终就一定能在一个集合中. 那么不管添加的是哪些边,最终形成的集合数都是一定的