集合劃分問題

2021-08-15 16:57:52 字數 1549 閱讀 3412

問題描述:

n個元素的集合可以劃分為若干個非空子集。例如,當n=4 時,集合可以劃分為15 個不同的非空子集如下:

,,,},

,,},

,,},

,,},

,,},

,,},

,,},

,},,},

,},,},

,},,},

,},}

給定正整數n,計算出n個元素的集合可以劃分為多少個不同的非空子集。 

所求的是bell 數 滿足遞推公式 b(n) =

所以這道題實際求第二類stirling數  s(n,m)

解決思想:

1.  若 m == 1    則s(n,m) = 1;    ( n >= 0 )

2.  若 m == 0    則s(n,m) = 0;    ( n >= 1  )

3.  若 n == m   則s(n,m) = 1;  

4 . 若非以上3中情況 則:

(1)  已知前s(n-1,m)的解決方案 , 第n個數可以向分出來的m個非空子集中的每乙個任意新增進去  共有m*s(n-1,m)方法

(2) 前n-1個數已經劃分成 m-1  剩餘第n個數單獨作為乙個非空子集新增進去  共有s(n-1,m-1)種方法

#include using namespace std;

int f( int n , int m )

//bell數

int main()

cout << sum << endl;

return 0;

}

對於遞迴中資料量為n 的時候    一般情況下寫出的遞迴公式裡面一定含有n  或者有其他題目中的引數  例如此題中的m 

遞迴最重要的思想: 至頂向下  假設已知前n-1時的解決方案  有了第n-1是的解決方案 才能求第n個 。  要求第n個時  可能有多種情況(每一種情況都能列出乙個遞迴公式) 最後將多種情況的結果相加即最終答案   所謂的終止條件即:  當遞迴回溯到了人腦可以算出的小資料量的時候,  "例如" 當n到了1  那麼可以知道n=2時的結果 知道2的結果可求3  繼而遞推到n。

這裡面的回溯和搜尋裡面的回溯雖然名字相同 但是意義略有不同  搜尋裡面的回溯一般是一種不斷去嘗試的過程 例如n皇后問題 一遍一遍的去嘗試 嘗試失敗就回來換個方向嘗試  直到找出答案。

而遞迴中的回溯  更像一種要得到那種終止條件不得已的將問題規模縮小  當得到答案後  再一層一層擴大直到得出最終答案。

遞迴的兩種結題技巧:

1.   回溯到底得到臨界條件 利用臨界條件遞推到  規模為n的為題。  例如:

int find(int x) //查詢根結點  

這是一段帶權並查集的路徑壓縮演算法。    在這段**中分為兩部分, find的函式中間截止  以上回溯,以下遞推  畫圖即可理解。

2. 在回溯的同時解決問題,  可能會不斷的進入臨界條件繼而返回,例如圖的遍歷,  但是圖的遍歷更像一種 一邊回溯一邊遞推一邊求解三者同時進行的思維模式。   這裡的遞推沒有具體值  是狀態量。   例子**後粘。

集合劃分問題

集合劃分問題 問題描述 n 個元素的集合可以劃分為若干個非空子集。例如,當n 4 時,集合可以劃分為15 不同的非空子集如下 其中,集合 由 1 個子集組成 集合 由2 子集組成 集合,由3子集組 成 集合,由4 子集組成。程式設計任務 給定正整數n 和m,計算出n元素的集合可以劃分為多少 不同的由...

集合劃分問題I

time limit 1000ms memory limit 32768k total submit 174accepted 64問題描述 n個元素的集合可以劃分為若干個非空子集。例如,當n 4 時,集合可以劃分為15 個不同的非空子集如下 演算法設計 給定正整數n,計算出n個元素的集合可以劃分為多...

集合劃分問題 演算法

問題描述 n個元素的集合可以劃分為若干個非空子集。例如,當n 4 時,集合可以劃分為15個不同的非空子集如下 其中,集合 由1個子集組成 集合,由2個子集組成 集合,由3 個子集組成 集合,由4個子集組成。程式設計任務 給定正整數n 和m,計算出n 個元素的集合可以劃分為多少個不同的由m 個 非空子...