第二部分 基礎算法 --第四章 遞歸算法1315:【例4.5】集合的劃分

1315:【例4.5】集合的劃分

時間限制: 1000 ms 內存限制: 65536 KB
提交數: 8438 通過數: 3559
【題目描述】
設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)。

【輸入】
給出n和k。

【輸出】
n個元素a1,a2,……,an 放入k個無標號盒子中去的劃分數S(n,k)。

【輸入樣例】
10 6
【輸出樣例】
22827


思路:

{an}是k子集合中的一個,於是我們只要把a1,a2,an-1劃分k-1個子集,劃分的個數共有s(n-1,k-1)

{an}不是k個子集中的任意一個子集,則an必與其他元素構成一個子集,則問題相當於先把a1,a2,a3…an-1劃分成k個子集,這 種情況下劃分數共有s(n-1,k)個,然後在把an加入到k個子集中的任意一箇中去,共有k種加入方式,這樣對於an的每一種加入方式,都可以使集合劃分爲k個子集,因此根據乘法原理,劃分數共有k*s(n-1,k)個

#include<iostream>
#include<cstring>
using namespace std;
long long s(int n,int k)
{
    if((n<k)||(k==0)) return 0;
    if((k==1)||(k==n)) return 1;
    return s(n-1,k-1)+k*s(n-1,k);
}
int main()
{
    int n,k;
    cin>>n>>k;
    cout<<s(n,k)<<endl;
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章