繁体   English   中英

计算具有n个元素的集合的分区数量为k个子集

[英]count number of partitions of a set with n elements into k subsets

该程序用于将具有n个元素的集合的分区数分成k个子集,这里我很困惑, return k*countP(n-1, k) + countP(n-1, k-1); 有人可以解释一下这里发生了什么吗? 为什么我们乘以k?

注意 - >我知道这不是计算DP分区数的最佳方法

// A C++ program to count number of partitions 
// of a set with n elements into k subsets 
#include<iostream> 
using namespace std; 

// Returns count of different partitions of n 
// elements in k subsets 
int countP(int n, int k) 
{ 
    // Base cases 
    if (n == 0 || k == 0 || k > n) 
        return 0; 
    if (k == 1 || k == n) 
        return 1; 

    // S(n+1, k) = k*S(n, k) + S(n, k-1) 
    return k*countP(n-1, k) + countP(n-1, k-1); 
} 

// Driver program 
int main() 
{ 
    cout << countP(3, 2); 
    return 0; 
} 

每个countP调用都隐式地考虑集合中的单个元素,让我们将其称为A.

countP(n-1, k-1)项来自A本身在集合中的情况。 在这种情况下,我们只需计算将所有其他元素(N-1)划分为(K-1)子集的方式,因为A本身占用一个子集。

然后, k*countP(n-1, k)项来自A本身不在集合中的情况。 因此,我们计算出将所有其他(N-1)值划分为K个子集的方法的数量,并乘以K,因为我们可以添加A到K个可能的子集。

例如,考虑集合[A,B,C,D] ,其中K=2

第一种情况countP(n-1, k-1)描述了以下情况:

{A, BCD}

第二种情况, k*countP(n-1, k) ,描述了以下情况:

2*({BC,D}, {BD,C}, {B,CD}) 

要么:

{ABC,D}, {ABD,C}, {AB,CD}, {BC,AD}, {BD,AC}, {B,ACD}

你提到的是第二类斯特林数,它列举了将一组n个对象划分为k个非空子集的方法的数量,并用 在此输入图像描述 要么 在此输入图像描述

它的递归关系是:

在此输入图像描述

对于初始条件为k > 0

在此输入图像描述

使用动态编程计算它比递归方法更快:

int secondKindStirlingNumber(int n, int k) {

    int sf[n + 1][n + 1];
    for (int i = 0; i < k; i++) {
        sf[i][i] = 1;
    }
    for (int i = 1; i < n + 1; i++) {
        for (int j = 1; j < k + 1; j++) {
            sf[i][j] = j * sf[i - 1][j] + sf[i - 1][j - 1];
        }
    }
    return sf[n][k];
}

我们如何获得countP(n,k) 假设我们已经将先前的n-1元素划分为一定数量的partion,现在我们有第n个元素,并且我们尝试进行k分区。

我们有两个选择:

  1. 我们已经将先前的n-1元素划分为k部分(我们有countP(n-1, k)这样做的方式),并且我们将这个第n个元素放入这些部分中的一个(我们有k选择)。 所以我们有k*countP(n-1, k)

要么:

  1. 我们将先前的n-1元素划分为k-1分区(我们有countP(n-1, k-1);这样做的方法),我们将第n个元素作为单个部分来实现k分区(我们只有一个选择:单独放置)。 所以我们有countP(n-1, k-1);

所以我们总结一下并得到结果。

基于 ,集合的分区是将集合的元素分组为非空子集,使得每个元素都包含在一个且仅包含一个子集中。 因此,n元素集的分区总数是Bell数 ,其计算如下: Bell数公式因此,如果要将公式转换为递归函数,它将类似于: k * countP(n-1, k)+ countP(n-1,k-1);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM