集合划分问题
给定正整数n和m,计算出n个元素的集合{1,2…n}可以划分为多少个不同的由m个非空子集组成的集合。
数据输入:
-
由文件input.txt提供输入数据.
-
文件的第1行是元素个数n和非空子集数m.
结果输出: -
程序运行结束时,将计算出的不同的由m个非空子集组成的集台数输出到文件output.txt中。
输入文件示例
4 3
输出文件示例
6
思路:
对于n个元素的集合,可以划分成由m(1<=m<=n)个子集构成的子集,如{{1}, {2}, {3}, {4}}就是由4个子集构成的非空子集。假设f(n,m)表示将n个元素的集合划分成由m个子集构成的集合的个数,那么可以这样来看: -
m==1时,则f(n,m)=1;只有{{1,2,3,4}}
-
n==m时,则f(n,m)=1;只有{{1},{2},{3},{4}}
-
若非以上两种情况,f(n,m)可以由下面两种情况构成
a.向n-1个元素划分成的m个集合里面添加一个新的元素,则有m*f(n-1,m)种方法;
b.向n-1个元素划分成的m-1个集合里添加一个由一个元素形成的独立的集合,则有f(n-1,m-1 )种方法。
在同根目录下建立文件input.txt:
#include "stdio.h"
#include "stdlib.h"
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()
{
int n, m,c;
FILE *fp,*fp1;
if ((fp = fopen("input.txt", "r")) == NULL) {
printf("文件错误\n");
exit(0);
}
fscanf(fp, "%d %d", &n,&m); //从文件中读取
fclose(fp);
c = f(n, m);
if ((fp1 = fopen("output.txt", "w")) == NULL)
{
printf("文件错误\n");
exit(0);
}
fprintf(fp1, "%d", c);//写入文件
fclose(fp1);
return 0;
}
运行结果: