题目描述
设S是一个具有nn个元素的集合,S=〈a1,a2,……,an〉S=〈a1,a2,……,an〉,现将S划分成k个满足下列条件的子集合S1,S2,……,SkS1,S2,……,Sk ,且满足:
则称S1,S2,……,Sk是集合S的一个划分。它相当于把S集合中的n个元素a1,a2,……,an放入k个(0<k≤n<30)无标号的盒子中,使得没有一个盒子为空。请你确定n个元素a1,a2,……,an放入k个无标号盒子中去的划分数S(n,k)。
输入格式
给出n和k。
输出格式
n个元素a1,a2,……,an放入k个无标号盒子中去的划分数S(n,k)。
样例输入
10 6
样例输出
22827
问题分析
n个元素分到k个集合
集合划分不可为空,所以最终的划分有两种方法:
1.n-1个元素划分到k个集合,第n个元素放在k个集合中的任意一个: k*f(n-1,k);
2.n-1个元素划分到k-1个集合,第n个元素单独占第k个集合:f(n-1,k-1);
注:最后数据可能非常大,要long long
代码
#include<bits/stdc++.h>
using namespace std;
long long f(int n,int k)
{
if(n<k) return 0;
if(k==0 ||n==0) return 0;
if(k==1 ||n==k) return 1;
return k*f(n-1,k)+f(n-1,k-1);
}
int main()
{
int n,k;
ios::sync_with_stdio(false);
//关闭同步流,可以提高程序的运行效率
// 通常在竞赛编程或需要高性能输入输出的应用程序中使用
//这里可以忽略
cin>>n>>k;
cout<<f(n,k);
return 0;
}