集合的划分
设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,……,ana1,a2,……,an 放入k个(0<k≤n<30)无标号的盒子中,使得没有一个盒子为空。请你确定n个元素a1,a2,……,an 放入k个无标号盒子中去的划分数S(n,k)。
思路:单独看一个元素a
1.元素a可以单独在一个盒子里,其它元素就放在另外k-1个盒子里,即S(n-1,k-1);
2.元素a可以和其他元素一起放在一个盒子中,先看其他元素,即S(n-1,k),再看a元素,a元素可以放在k个盒子中的任意一个,总的就是k*S(n-1,k);
边界的判定:当k==1或者k==n时,都只有一种情况,return 1;
当n < k或者k==0时,都return 0;
代码如下:
#include<iostream>
using namespace std;
#define ll long long
int n,k;
ll dfs(int n,int k)
{
if(k==1||k==n)return 1;
if(n<k||k==0)return 0;
return dfs(n-1,k-1)+k*dfs(n-1,k);
}
int main()
{
cin>>n>>k;
cout<<dfs(n,k);
return 0;
}