目录
一、题目描述
题目描述:
n个元素的集合 { 1, 2, 3, ````, n} 可以划分为若干个非空子集。例如:当n = 4 时,集合 { 1, 2, 3, 4} 可以划分为 15 个不同的非空子集,如下:
1 个子集组成:{ { 1, 2, 3, 4 } }
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 } }
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 } }
4 个子集组成:{ { 1 }, { 2 }, { 3 }, { 4 } }
二、编程任务
给定正整数 n 和 m ,计算出 n 个元素的集合 { 1, 2, 3, ```` , n } 可以划分为多少个不同的由 m 个非空子集组成的集合。
数据输入:
n m
结果输出:
个数
三、思路解析
1.易知特殊情况:
m == 1 时,F ( 1, 1 ) = 1; //只需要分成一份
n == m 时,F ( n , m ) = 1; //当元素个数和份数一样时,每一个元素就为一份
2.一般情况:( 将问题简单化 )
a.将第 i 个元素单独放,其余 n - 1 个元素分成 m - 1 份 : F ( n -1, m - 1 ) ;
b.将第 i 个元素插入其余的 n - 1 个元素分成的 m 份中,有 m 种插入的位置:
m * F ( n -1, m );
Others:
类似于排列组合中的
个人的一点类似联想。。。。希望能够帮助到理解。。。。
四、代码实现
#include <iostream>
using namespace std;
int F( int n, int m)
{
if ( m == 1 || n == m ) return 1;
else return F( n - 1, m - 1) + m * F( n - 1, m);
}
int main()
{
cout << "请输入需要划分的集合的元素的个数和份数:" << endl;
int n, m;
cin >> n >> m;
int res = F(n,m);
printf("%d个元素的集合可以划分为%d种的%d份的非空子集!",n,res,m);
}
测试数据:F( 1, 1 ) = 1;
F( 2, 1 ) = 1, F( 2, 2 ) = 1;
F( 3, 1 ) = 1, F( 3, 2 ) = 3, F( 3, 3 ) = 1;
F( 4, 1 ) = 1, F( 4, 2 ) = 7, F( 4, 3 ) = 6, F( 4, 4 ) = 1;
五、算法分析
主要掌握如何简化问题,找特殊的情况,以及如何一般化问题。