📜  响铃编号(对集合进行分区的方式数)

📅  最后修改于: 2021-05-04 10:46:06             🧑  作者: Mango

给定一组n个元素,请找到对其进行分区的多种方法。
例子:

Input:  n = 2
Output: Number of ways = 2
Explanation: Let the set be {1, 2}
            { {1}, {2} } 
            { {1, 2} }

Input:  n = 3
Output: Number of ways = 5
Explanation: Let the set be {1, 2, 3}
             { {1}, {2}, {3} }
             { {1}, {2, 3} }
             { {2}, {1, 3} }
             { {3}, {1, 2} }
             { {1, 2, 3} }. 

上述问题的解决方案是贝尔号码。
什么是响铃号码?
S(n,k)为n个元素在k个集合中的划分总数。当k = 1至n时,第n个响铃编号的值是S(n,k)的和。
Bell(n) = \sum_{k=0}^{n}S(n,k)
S(n,k)的值可以递归定义为S(n + 1,k)= k * S(n,k)+ S(n,k-1)
以上递归公式如何工作?
当我们将第(n + 1)个元素添加到k个分区时,有两种可能性。
1)将其作为单个元素集添加到现有分区,即S(n,k-1)
2)将其添加到每个分区的所有集合中,即k * S(n,k)
S(n,k)被称为第二类斯特林数
前几个贝尔编号是1、1、2、5、15、52、203,…。
一种简单的计算第n个Bell数的方法是:对于k = 1到n,一个接一个地计算S(n,k),并返回所有计算值的总和。有关S(n,k)的计算,请参考此内容。
更好的方法是使用Bell Triangle。下面是前几个贝尔编号的示例贝尔三角形。

1
1 2
2 3 5
5 7 10 15
15 20 27 37 52

使用以下公式构造三角形。

// If this is first column of current row 'i'
If j == 0
   // Then copy last entry of previous row
   // Note that i'th row has i entries
   Bell(i, j) = Bell(i-1, i-1) 

// If this is not first column of current row
Else 
   // Then this element is sum of previous element 
   // in current row and the element just above the
   // previous element
   Bell(i, j) = Bell(i-1, j-1) + Bell(i, j-1)

解释
然后Bell(n,k)计算集合{1,2,…,n + 1}的分区数,其中元素k + 1是在其集合中可以单独存在的最大元素。
例如,Bell(3,2)是3,它是{1,2,3,4}的分区数的计数,其中3是最大的单例元素。有三个这样的分区:

{1}, {2, 4}, {3}
    {1, 4}, {2}, {3}
    {1, 2, 4}, {3}. 

下面是上述递归公式的基于动态编程的实现。

C++
// A C++ program to find n'th Bell number
#include
using namespace std;
 
int bellNumber(int n)
{
   int bell[n+1][n+1];
   bell[0][0] = 1;
   for (int i=1; i<=n; i++)
   {
      // Explicitly fill for j = 0
      bell[i][0] = bell[i-1][i-1];
 
      // Fill for remaining values of j
      for (int j=1; j<=i; j++)
         bell[i][j] = bell[i-1][j-1] + bell[i][j-1];
   }
   return bell[n][0];
}
 
// Driver program
int main()
{
   for (int n=0; n<=5; n++)
      cout << "Bell Number " << n << " is "
           << bellNumber(n) << endl;
   return 0;
}


Java
// Java program to find n'th Bell number
import java.io.*;
 
class GFG
{
    // Function to find n'th Bell Number
    static int bellNumber(int n)
    {
        int[][] bell = new int[n+1][n+1];
        bell[0][0] = 1;
         
        for (int i=1; i<=n; i++)
        {
            // Explicitly fill for j = 0
            bell[i][0] = bell[i-1][i-1];
  
            // Fill for remaining values of j
            for (int j=1; j<=i; j++)
                bell[i][j] = bell[i-1][j-1] + bell[i][j-1];
        }
         
        return bell[n][0];
    }
     
    // Driver program
    public static void main (String[] args)
    {
        for (int n=0; n<=5; n++)
            System.out.println("Bell Number "+ n +
                            " is "+bellNumber(n));
    }
}
 
// This code is contributed by Pramod Kumar


Python3
# A Python program to find n'th Bell number
 
def bellNumber(n):
 
    bell = [[0 for i in range(n+1)] for j in range(n+1)]
    bell[0][0] = 1
    for i in range(1, n+1):
 
        # Explicitly fill for j = 0
        bell[i][0] = bell[i-1][i-1]
 
        # Fill for remaining values of j
        for j in range(1, i+1):
            bell[i][j] = bell[i-1][j-1] + bell[i][j-1]
 
    return bell[n][0]
 
# Driver program
for n in range(6):
    print('Bell Number', n, 'is', bellNumber(n))
 
# This code is contributed by Soumen Ghosh


C#
// C# program to find n'th Bell number
using System;
 
class GFG {
     
    // Function to find n'th
    // Bell Number
    static int bellNumber(int n)
    {
        int[,] bell = new int[n + 1,
                              n + 1];
        bell[0, 0] = 1;
         
        for (int i = 1; i <= n; i++)
        {
             
            // Explicitly fill for j = 0
            bell[i, 0] = bell[i - 1, i - 1];
 
            // Fill for remaining values of j
            for (int j = 1; j <= i; j++)
                bell[i, j] = bell[i - 1, j - 1] +
                             bell[i, j - 1];
        }
         
        return bell[n, 0];
    }
     
    // Driver Code
    public static void Main ()
    {
        for (int n = 0; n <= 5; n++)
            Console.WriteLine("Bell Number "+ n +
                              " is "+bellNumber(n));
    }
}
 
// This code is contributed by nitin mittal.


PHP


Javascript


输出:

Bell Number 0 is 1
Bell Number 1 is 1
Bell Number 2 is 2
Bell Number 3 is 5
Bell Number 4 is 15
Bell Number 5 is 52