集合的划分

集合的划分

Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 19   Accepted Submission(s) : 7

Font: Times New Roman | Verdana | Georgia

Font Size:  

Problem Description

设S是一个具有n个元素的集合,S={a1,a2,……,an},现将S划分成k个满足下列条件的子集合S1,S2,……,Sk ,且满足:
1. Si不为空集
2. Si与Sj的交集为空集(1<=i,j<=k i!=j)
3. S1、S2、S3..Sk的并集为S。
则称S1,S2,……,Sk是集合S的一个划分。它相当于把S集合中的n个元素a1 ,a2,……,an 放入k个(0<k≤n<30=无标号的盒子中,使得没有一个盒子为空。请你确定n个元素a1 ,a2 ,……,an 放入k个无标号盒子中去的划分数S(n,k)。

Input

输入有多组数据,对于输入每组数据有两个整数n和k。

Output

对于每组输入输出划分数。

Sample Input

10  6

Sample Output

22827

Author

/*对于任一元素a(n)有两种情况 1:a(n)存在于k个子集中,那么我们只需要把剩下的a(1)-a(n-1)划分到k-1个子集 则digui(i-1,j-1)
2.a(n)不是k个子集中的一个,那么a(n)必定和其他元素构成子集那么就是把a(1)-a(n-1)划分为k个子集然后把a(n)
任意放入一个子集则有j*digui(i-1,j)
递归关系就是:digui(i-1,j-1)+j*digui(i-1,j)*/
#include <iostream>
#include <stdio.h>
using namespace std;
int digui(int i,int j)
{
    if(j==0||i<j) //如果没有盒子或者盒子个数大于球的个数
        return 0;
    else if(j==1||j==i)//如果只有一个盒子或者球和盒子的个数相等
        return 1;
    else if(j>0&&i>j)
        return digui(i-1,j-1)+j*digui(i-1,j);

}
int main ()
{  int n,k;
while(scanf("%d%d",&n,&k)!=EOF)
{
    cout<<digui(n,k)<<endl;
}
    return 0;
}

猜你喜欢

转载自blog.csdn.net/u010760034/article/details/17080075