题目:n个元素的集合{1,2,.,n }可以划分为若干个非空子集。
例如,当n=4 时,集合{1,2,3,4}可以划分为15个不同的非空子集如下:
{1},{2},{3},{4}}, {{1,2},{3},{4}},
{{1,3},{2},{4}}, {{1,4},{2},{3}},
{{2,3},{1},{4}}, {{2,4},{1},{3}},
{{3,4},{1},{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,2,3,4}}
算法思路:
对于n个元素的集合,可以划分成由m(1<=m<=n)个子集构成的子集,如 {{1},{2},{3},{4}}
就是由4个子集构成的非空子集。假设f(n,m)表示将n个元素的集合划分成由m个子集构成的集合的个数,
那么可以这样来看:
(1)若m==1,则f(n,m)=1;
(2)若n==m,则f(n,m)=1;
(3)若非以上两种情况,f(n,m)可以由下面两种情况构成
a.向n-1个元素划分成的m个集合里面添加一个新的元素,则有m*f(n-1,m)种方法;
b.向n-1个元素划分成的m-1个集合里添加一个由一个元素形成的独立的集合,则有f(n-1,m-1)种方法。
#include <iostream>
using namespace std;
int Fun(int n,int m)///将n个元素划分为m个集合
{
if((m==1)||(n==m))
return 1;
else
return (Fun(n-1,m-1))+(m*Fun(n-1,m));
}
int main()
{
int n,m;
cout << "请输入输入集合总元素n:";
cin>>n;
int sum=0;
for(int i=1;i<=n;i++)
{
sum+=Fun(n,i);
}
cout << endl<<"输出集合划分的非空总子集数"<<sum;
return 0;
}
运行结果如下: