S(r, n) 表示我们可以将 r 个对象围绕长度为 n 的无法区分的圆排列的方式数,并且每个圆 n 必须至少有一个对象围绕它。
例子:
Input: r = 9, n = 2
Output: 109584
Input: r = 6, n = 3
Output: 225
特殊情况是:
- S(r, 0) = 0,微不足道。
- S(r, 1) 表示循环排列,它等于 (r – 1)!
- S(r, n) 其中 r = n,等于 1。
- S(r, r -1) = rC2
斯特林数的一个重要等式 S(r, n) = S(r – 1, n – 1) + (r – 1) * S(r – 1, n)
方法:为简单起见,用 1, 2, …, r 表示 r 个不同的对象。考虑对象“1”。在物体的任何排列中,要么
- “1”是圆圈中唯一的对象或
- “1”与其他人混在一起围成一圈。
在情况 1 中,有 s(r – 1, n – 1) 种方式来形成这样的安排。在情况 2 中,首先将 r_1 个对象 2, 3, …, r 以 s(r_1, n) 的方式放入 n 个圆圈中;那么“1”可以放置在 r-1 个不同空间之一中,在相应的 r-1 个不同对象的“直接右边”。根据乘法原理,在情况 2 中,有 (r_1)s(r_1,n) 种方式来形成这种排列。现在等式来自 s(r,n) 的定义和加法原理。
使用初始值 S(0, 0) = 1, s(r, 0) = 0 for r > 1 and s(r, 1) = (r — 1)!对于 r > 1,并应用我们证明的恒等式,我们可以通过递归方式轻松计算得到斯特林数。
在代码中,我们有三个函数用于生成斯特林数,它们是 nCr(n, r),这是一个计算我们所说的函数(n – choose – r),我们可以采用的方法数来自 n 个对象的 r 个对象,没有排序的重要性。毫不奇怪,factorial (int n) 用于计算数字 n 的阶乘。函数斯特林数(r,n)使用上面讨论的四种基本情况递归工作,然后使用我们证明的身份递归。
下面是上述方法的实现:
C++
// C++ program to implement above approach
#include
using namespace std;
// Calculating factorial of an integer n.
long long factorial(int n)
{
// Our base cases of factorial 0! = 1! = 1
if (n == 0)
return 1;
// n can't be less than 0.
if (n < 0)
return -1;
long long res = 1;
for (int i = 2; i < n + 1; ++i)
res *= i;
return res;
}
// Function to compute the number of combination
// of r objects out of n objects.
int nCr(int n, int r)
{
// r cant be more than n so we'd like the
// program to crash if the user entered
// wrong input.
if (r > n)
return -1;
if (n == r)
return 1;
if (r == 0)
return 1;
// nCr(n, r) = nCr(n - 1, r - 1) + nCr(n - 1, r)
return nCr(n - 1, r - 1) + nCr(n - 1, r);
}
// Function to calculate the Stirling numbers.
// The base cases which were discussed above are handled
// to stop the recursive calls.
long long stirlingNumber(int r, int n)
{
// n can't be more than
// r, s(r, 0) = 0.
if (n > r)
return -1;
if (n == 0)
return 0;
if (r == n)
return 1;
if (n == 1)
return factorial(r - 1);
if (r - n == 1)
return nCr(r, 2);
else
return stirlingNumber(r - 1, n - 1)
+ (r - 1) * stirlingNumber(r - 1, n);
}
// Driver program
int main()
{
// Calculating the stirling number s(9, 2)
int r = 9, n = 2;
long long val = stirlingNumber(r, n);
if (val == -1)
cout << " No stirling number";
else
cout << "The Stirling Number s(" << r
<< ", " << n << ") is : " << val;
return 0;
}
Java
// Java program to implement
// above approach
import java.io.*;
class GFG
{
// Calculating factorial of
// an integer n.
static long factorial(int n)
{
// Our base cases of factorial
// 0! = 1! = 1
if (n == 0)
return 1;
// n can't be less than 0.
if (n < 0)
return -1;
long res = 1;
for (int i = 2; i < n + 1; ++i)
res *= i;
return res;
}
// Function to compute the number
// of combination of r objects
// out of n objects.
static int nCr(int n, int r)
{
// r cant be more than n so
// we'd like the program to
// crash if the user entered
// wrong input.
if (r > n)
return -1;
if (n == r)
return 1;
if (r == 0)
return 1;
return nCr(n - 1, r - 1) +
nCr(n - 1, r);
}
// Function to calculate the Stirling
// numbers. The base cases which were
// discussed above are handled to stop
// the recursive calls.
static long stirlingNumber(int r, int n)
{
// n can't be more than
// r, s(r, 0) = 0.
if (n > r)
return -1;
if (n == 0)
return 0;
if (r == n)
return 1;
if (n == 1)
return factorial(r - 1);
if (r - n == 1)
return nCr(r, 2);
else
return stirlingNumber(r - 1, n - 1) +
(r - 1) *
stirlingNumber(r - 1, n);
}
// Driver Code
public static void main (String[] args)
{
// Calculating the stirling number s(9, 2)
int r = 9, n = 2;
long val = stirlingNumber(r, n);
if (val == -1)
System.out.println(" No stirling number");
else
System.out.println( "The Stirling Number s(" +
r + ", " + n + ") is : " + val);
}
}
// This Code is Contributed by anuj_67
Python 3
# Python 3 program to implement above approach
# Function to compute the number of combination
# of r objects out of n objects.
# nCr(n, n) = 1, nCr(n, 0) = 1, and these are
# the base cases.
def nCr(n, r):
if(n == r):
return 1
if(r == 0):
return 1
# nCr(n, r) = nCr(n - 1, r - 1) + nCr(n - 1, r)
return nCr(n - 1, r - 1) + nCr(n - 1, r)
# This function is used to calculate the
# factorial of a number n.
def factorial(n):
res = 1
# 1 ! = 0 ! = 1
if(n <= 1):
return res
for i in range(1, n + 1):
res *= i
return res
# Main function to calculate the Stirling numbers.
# the base cases which were discussed above are
# handled to stop the recursive call, n can't be
# more than r, s(r, 0) = 0.
# s(r, r) = 1. s(r, 1) = (r - 1)!.
# s(r, r - 1) = nCr(r, 2)
# else as we proved, s(r, n) = s(r - 1, n - 1)
# + (r - 1) * s(r - 1, n)
def stirlingNumber(r, n):
if(r == n):
return 1
if(n == 0):
return 0
if(n == r -1):
return nCr(r, 2)
if(r - n == 1):
return factorial(r - 1)
return (stirlingNumber(r - 1, n - 1)
+ (r - 1) * stirlingNumber(r - 1, n))
r, n = 9, 2
print(stirlingNumber(r, n))
C#
// C# program to implement
// above approach
using System;
class GFG
{
// Calculating factorial of
// an integer n.
static long factorial(int n)
{
// Our base cases of factorial
// 0! = 1! = 1
if (n == 0)
return 1;
// n can't be less than 0.
if (n < 0)
return -1;
long res = 1;
for (int i = 2; i < n + 1; ++i)
res *= i;
return res;
}
// Function to compute the number
// of combination of r objects
// out of n objects.
static int nCr(int n, int r)
{
// r cant be more than n so
// we'd like the program to
// crash if the user entered
// wrong input.
if (r > n)
return -1;
if (n == r)
return 1;
if (r == 0)
return 1;
return nCr(n - 1, r - 1) +
nCr(n - 1, r);
}
// Function to calculate the Stirling
// numbers. The base cases which were
// discussed above are handled to stop
// the recursive calls.
static long stirlingNumber(int r, int n)
{
// n can't be more than
// r, s(r, 0) = 0.
if (n > r)
return -1;
if (n == 0)
return 0;
if (r == n)
return 1;
if (n == 1)
return factorial(r - 1);
if (r - n == 1)
return nCr(r, 2);
else
return stirlingNumber(r - 1, n - 1) +
(r - 1) *
stirlingNumber(r - 1, n);
}
// Driver Code
public static void Main ()
{
// Calculating the stirling
// number s(9, 2)
int r = 9, n = 2;
long val = stirlingNumber(r, n);
if (val == -1)
Console.WriteLine(" No stirling number");
else
Console.WriteLine( "The Stirling Number s(" +
r + ", " + n + ") is : " + val);
}
}
// This code is contributed by inder_verma..
PHP
$n)
return -1;
if ($n == $r)
return 1;
if ($r == 0)
return 1;
// nCr($n, $r) = nCr($n - 1, $r - 1) + nCr($n - 1, $r)
return nCr($n - 1, $r - 1) + nCr($n - 1, $r);
}
// Function to calculate the Stirling numbers.
// The base cases which were discussed above are handled
// to stop the recursive calls.
function stirlingNumber($r, $n)
{
// n can't be more than
// r, s(r, 0) = 0.
if ($n > $r)
return -1;
if ($n == 0)
return 0;
if ($r == $n)
return 1;
if ($n == 1)
return factorial($r - 1);
if ($r - $n == 1)
return nCr($r, 2);
else
return stirlingNumber($r - 1, $n - 1)
+ ($r - 1) * stirlingNumber($r - 1, $n);
}
// Calculating the stirling number s(9, 2)
$r = 9;
$n = 2;
$val = stirlingNumber($r, $n);
if ($val == -1)
echo " No stirling number";
else
echo "The Stirling Number s(", $r
,", " , $n , ") is : " , $val;
// This code is contributed by ANKITRAI1
?>
Javascript
The Stirling Number s(9, 2) is : 109584
注:上述方案可以通过动态规划进行优化。请参考 Bell Numbers (Number of way to Partition a Set) 为例。
请参阅第一类斯特林数以了解有关斯特林数的更多信息。
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。