问题描述:
在数学中,集合 X 的划分是把 X 分割到覆盖了 X 的全部元素的不交叠的“部分”或“块”或“单元”中。更加形式的说,这些“单元”关于被划分的集合是既全无遗漏又相互排斥的。
假设集合A = {1,2,3}。根据其划分的集合数,划分结果如下:
划分成一个集合:
A1 = {1,2,3};
共一种方法
划分成两个集合:
A1 = {1,2},A2 = {3};
或
A1 = {1,3},A2 = {2};
或
A1 = {1},A2 = {2,3}。
共三种方法
划分成三个集合:
A1 = {1},A2 = {2},A3 = {3}。
共一种方法。
现给定一个集合,有m个元素,要把其划分成n个集合。求对其进行划分的方法数及每种划分的内容。
思路解析:
利用动态规划思想。P[i][j]表示将一个有i个元素的集合划分成j个单元的方法数,则有如下关系:
P[i][j] = P[i - 1][j - 1] + j * P[i - 1][j];
即P[i][j]由两部分组成:
- 在将i - 1个元素划分成 j - 1个元素的基础上,将新加入的第i个元素单独划成一类。共有P[i - 1][j - 1]种方法。
- 在将i - 1个元素划分成j类的基础上,将新加入的第i个元素放到其中的每一类中,共有 j*P[i - 1][j]种方法。
因此,P[i][j]为以上两部分的加和,得出上述递推式。
程序代码:
#include <iostream>
#include <math.h>
using namespace std;
#define MAX 11