非空子集个数计算

该博客探讨了如何计算一个包含n个元素的集合可以被划分为m个非空子集的不同方式。通过实例和递推关系F(n,m)=F(n-1,m-1)+m*F(n-1,m),解释了计算过程,并给出了特定情况下的F(n,m)值。" 103775833,1235738,基于注意力机制的BIRD模型:电商色情产品检测,"['深度学习', '自然语言处理', '文本分类', '电子商务', '信息检索']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:n个元素的集合{1,2,.....,n},可以划分为若干个非空子集,如,当n=4时,集合{1,2,3,4}可以划分为15个不同的非空子集如下:

由4个子集组成:

{{1},{2},{3},{4}}

由3个子集组成:

{{1,2},{3},{4}}

{{1,3},{2},{4}}

{{1,4},{2},{3}}

{{2,3},{1},{4}}

{{2,4},{1},{3}}

{{3,4},{1},{2}}

由2个子集组成:

{{1,2},{3,4}}

{{1,3},{2,4}}

{{1,4},{2,3}}

{{1,2,3},{4}}

{{1,2,4},{3}}

{{1,3,4},{2}}

{{2,3,4},{1}}

由1个子集组成:

{{1,2,3,4}}

给定正整数n和m,计算出n个元素的集合{1,2,...,n}可以划分为多少个不同的由m个非空子集组成的集合?

 

Thinking:

 设F(n,m)为n个元素集合{1,2,...,n}中划分出m个非空子集组成的集合个数 (1<=m<=n)

如:

F(2,1)=1,  {{1,2}}

F(2,2)=1;  {{1},{2}}

 

F(3,1)=1,  {{1,2,3}}

F(3,2)=3,  {{1,2},{3}},  {{1,3},{2}},  {{2,3},{1}}

F(3,3)=1;  {{1},{2},{3}}

 

F(4,1)=1   {{1,2,3,4}}

F(4,2)=7,  {{1,2},{3,4}},    {{1,3},{2,4}},    {{1,4},{2,3}},    {{1,2,3},{4}},    {{1,2,4},{3}},    {{1,3,4},{2}},    {{2,3,4},{1}}

F(4,3)=6,  {{1,2},{3},{4}},    {{1,3},{2},{4}},    {{1,4},{2},{3}},    {{2,3},{1},{4}},     {{2,4},{1},{3}},     {{3,4},{1},{2}}

F(4,4)=1,  {{1},{2},{3},{4}}

        

接下来,演示F(n,m)的形成过程

 

F(3,2)形成过程:

在F(2,1)中,添加一个元素,即为

 {{1,2}}->{{1,2},{3}}

在F(2,2)中,添加一个元素,且不改变m,即为

{{1},{2}}->{{1,3},{2}}  || {{1},{2,3}}

 

F(4,2)形成过程:

在F(3,1)中,添加一个元素,即为

{{1,2,3}}->{{1,2,3},{4}}

在F(3,2)中,添加一个元素,且不改变m,即为

{{1,2},{3}}->{{1,2,4},{4}} || {{1,2},{3,4}}

{{1,3},{2}}->{{1,3,4},{2}} || {{1,3},{2,4}}

{{2,3},{1}}->{{2,3,4},{1}} || {{2,3},{1,4}}

 

F(4,3)形成过程:

在F(3,2)中,添加一个元素,即为

{{1,2},{3}}->{{1,2},{3,4}}

{{1,3},{2}}->{{1,3},{2,4}}

{{2,3},{1}}->{{2,3},{1,4}}

在F(3,3)中,添加一个元素,且不改变m,即为

{{1},{2},{3}}->{{1,4},{2},{3}}  ||  {{1},{2,4},{3}}  ||  {{1},{2},{3,4}}

 

看完了F(3,2),F(4,2),F(4,3)的形成过程,大概可以体会到一点味道了,若要求F(n,m),则要先求F(n-1,m)和F(n-1,m-1).

再想想,发现有规律如下:

F(n,m)=F(n-1,m-1)+m*F(n-1,m);(n>=2,m>=2)

还有一些易知条件:

F(n,1)=F(n,n)=1;      (n>1)

F(n,0)=0;                   

F(n,m)=0;                  (m>n)

 

code:

#include<iostream>
using namespace std;
double arr[250][250];
int n;//n最多只能输入200左右 否则会overflow 
void init()
{
	for(int i=1;i<=n;i++)
	{
		arr[i][1]=1;
		arr[i][i]=1;
	}
} 
void function()
{
	for(int i=2;i<=n;i++)
		for(int j=2;j<=i;j++)
			arr[i][j]=arr[i-1][j-1]+j*arr[i-1][j];
}
void output()
{
	for(int i=1;i<=n;i++)
		cout<<"F("<<n<<","<<i<<") : "<<arr[n][i]<<endl;
}
int  main()
{
	cin>>n;
	
	init();
	
	function();
	
	output();
	
	return 0;
}


 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值