1. 程式人生 > 實用技巧 >集合劃分

集合劃分

覆蓋 : 若把集合A分成若干個稱為分塊的非空子集, 使得A中的每個元素至少屬於一個分塊, 那麼這些分塊的全體集合稱為A的一個覆蓋.

劃分 : A中的每個元素僅屬於一個分塊, 那麼這些分塊的全體構成的集合稱為A的劃分.

那麼有 n 個元素的集合A有多少種劃分?

\[\begin{align*} f[1] &= 1 \quad f[2] = 2 \\ f[n] &= C_{n-1}^0f[0] + C_{n-1}^1f[1] + C_{n-1}^2f[2] + ...... + C_{n-1}^{n-1}f[n-1] \end{align*} \]

#include <bits/stdc++.h>
using namespace std;
#define IO ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
inline int lowbit(int x) { return x & (-x); }
#define ll long long
#define pb push_back
#define PII pair<int, int>
#define fi first
#define se second
#define inf 0x3f3f3f3f
const int N = 1010;
ll C[N][N];
ll f[N];

void init() {
    for (int i = 0; i <= N; ++i)
        for (int j = 0; j <= i; ++j)
            if (j == 0) C[i][j] = 1;
            else C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
}

int main() {
    IO;
    init();
    int n;
    cin >> n;
    memset(f, 0, sizeof f);
    f[0] = 1;
    for (int i = 1; i <= n; ++i)
        for (int j = 0; j < i; ++j) f[i] += C[i - 1][j] * f[j];
    cout << f[n]; 
}