集合的划分(setsub)
题目描述
设s是一个具有n个元素的集合,s={a1,a2,......,an},现将s划分成K个满足下列条件的子集合s1,s2,......,sk,且满足:
1.si≠φ
2.si∩sj=φ(1≤i,j≤ki≠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)。
输入
一行,两个整数n、k
输出
一行,一个整数s(n,k)
样例输入
10 6
样例输出
22827
【分析】
我一开始觉得这题写个暴搜应该能AC。
然而我写了,没过。可能因为我太弱了,也可能因为今天中午在食堂干饭没有理同班同学,rp--。
回归正题。原题写的不太明白。不过看数据点应该是输出划分出的集合个数。
举个例子。
当n=5时,
k=1-->s(n,k)=1
k=2-->s(n,k)=15
k=3-->s(n,k)=25
k=4-->s(n,k)=10
由此可以推出:
s(n,k)=s(n-1,k-1)+k*s(n-1,k).
当k=1或k=n时,s(n,k)=1;
当n<k或k<0时,s(n,k)=0.
1 #include <bits/stdc++.h> 2 using namespace std; 3 int s(int a,int b) 4 { 5 if(b<=0||a<=0||a<b) 6 { 7 return 0; 8 } 9 if(b==1||b==a) 10 { 11 return 1; 12 } 13 return s(a-1,b-1)+s(a-1,b)*b; 14 } 15 int main() 16 { 17 int n,k; 18 scanf("%d %d",&n,&k); 19 printf("%d",s(n,k)) ; 20 return 0; 21 }