問題描述:
n個元素的集合可以劃分為若干個非空子集。
例如,當n=4 時,集合可以劃分為15 個不同的非空子集如下:
,,,},
,,},
,,},
,,},
,,},
,,},
,,},
,},,},
,},,},
,},,},
,},}
給定正整數n,計算出n個元素的集合可以劃分為多少個不同的非空子集。
其中設q(n,m)表示n個數可以表示為m個非空子集。
根據m和n的關係,可以分為以下情況:
第一種情況:
n=1時,只有乙個元素,所以只能拆分為乙個子集和;
第二種情況:
m=1時,只能拆分為乙個子集和就是他自己;
第三種情況:
m=0或者n=0時,毫無疑問返回0;
第四種情況:
m>n時,拆分的子集和數大於元素數,因為不能拆分為空集,所以這種情況沒法拆分,所以return 0;
第五種情況:
m=n時,元素數等於子集和的數,所以為1;
第六種情況:
n>m時,也是最普遍的情況,這個可以劃分為兩種情況:
第乙個是,將n個數中選出乙個劃分為乙個集合則剩下n-1個數拆分成m-1個集合,即q(n,m)=q(n-1,m-1);
第二個是,將n-1個數拆分成m個集合,然後最後乙個數放到這m個集合中的乙個,也就是有m個情況,所以q(n,m)=m*q(n-1,m);
所以第六種情況為q(n-1,m-1)+m*q(n-1,m);
#includeint q(int n,int m)
int main()
printf("可以劃分為%d個集合",count);
return 0;
}
與該問題相似的問題可以順便練練手:
整數拆分問題
集合的劃分 遞迴
題目描述 設s是乙個具有n個元素的集合,s 現將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集合中的n個元素a1,a2,an放入k個 0 k n 30 無標號...
集合劃分問題 演算法
問題描述 n個元素的集合可以劃分為若干個非空子集。例如,當n 4 時,集合可以劃分為15個不同的非空子集如下 其中,集合 由1個子集組成 集合,由2個子集組成 集合,由3 個子集組成 集合,由4個子集組成。程式設計任務 給定正整數n 和m,計算出n 個元素的集合可以劃分為多少個不同的由m 個 非空子...
遞推遞迴 集合的劃分
設s是乙個具有n個元素的集合,s 現將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集合中的n個元素a1,a2,an放入k個 0 k n 30 無標號的盒子中,...