1. 程式人生 > 實用技巧 >集合的劃分(setsub)

集合的劃分(setsub)

集合的劃分(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 }