[组合数学] 第一类,第二类Stirling数,Bell数

一.第二类Stirling数

定理:第二类Stirling数S(p,k)计数的是把p元素集合划分到k个不可区分的盒子里且没有空盒子的划分个数。

证明:元素在拿些盒子并不重要,唯一重要的是各个盒子里装的是什么,而不管哪个盒子装了什么。

递推公式有:S(p,p)=1 (p>=0)         S(p,0)=0  (p>=1)         S(p,k)=k*S(p-1,k)+S(p-1,k-1)   (1<=k<=p-1)
。考虑将前p个正整数,1,2,.....p的集合作为要被划分的集合,把

{1,2,.....p}分到k个非空且不可区分的盒子的划分有两种情况:

(1)那些使得p自己单独在一个盒子的划分,存在有S(p-1,k-1)种划分个数

(2)那些使得p不单独自己在一个盒子的划分,存在有 k*S(p-1,k)种划分个数

考虑第二种情况,p不单独自己在一个盒子,也就是p和其他元素在一个集合里面,也就是说在没有放p之前,有p-1个元素已经分到了k个非空且不可区分的盒子里面(划

分个数为S(p-1,k),那么现在问题是把p放在哪个盒子里面呢,有k种选择,所以存在有k*S(p-1,k)。

模板:

long long s[maxn][maxn];//存放要求的Stirling数
const long long mod=1e9+7;//取模

void init()//预处理
{
    memset(s,0,sizeof(s));
    s[1][1]=1;
    for(int i=2;i<=maxn-1;i++)
        for(int j=1;j<=i;j++)
    {
        s[i][j]=s[i-1][j-1]+j*s[i-1][j];
        if(s[i][j]>=mod)
            s[i][j]%=mod;
    }
}

注意:要用long long类型,当元素个数>20,就超int类型了。

扩展:k! *S(p,k) 计数的是把p元素集合划分到k个可区分的盒子里且没有空盒子的划分个数。

二.Bell数

定理:Bell数B(p)是将p元素集合分到非空且不可区分盒子的划分个数(没有说分到几个盒子里面)。

B(p)=S(p,0)+S(p,1)+.....+S(p,k)

所以要求Bell数就要先求出第二类Stiring数。

三.第一类Stirling数

定理:第一类Stirling数s(p,k)计数的是把p个对象排成k个非空循环排列的方法数。

证明:把上述定理叙述中的循环排列叫做圆圈。递推公式为:

s(p,p)=1 (p>=0)    有p个人和p个圆圈,每个圆圈就只有一个人

s(p,0)=0 (p>=1)    如果至少有1个人,那么任何的安排都至少包含一个圆圈

s(p,k)=(p-1)*s(p-1,k)+s(p-1,k-1)

设人被标上1,2,.....p。将这p个人排成k个圆圈有两种情况。第一种排法是在一个圆圈里只有标号为p的人自己,排法有s(p-1,k-1)个。第二种排法中,p至少和另一个人在一

个圆圈里。这些排法可以通过把1,2....p-1排成k个圆圈再把p放在1,2....p-1任何一人的左边得到,因此第二种类型的排法共有(p-1)*s(p-1,k)种排法。

在证明中我们所做的就是把{1,2,...,p}划分到k个非空且不可区分的盒子,然后将每个盒子中的元素排成一个循环排列。

模板:

long long s[maxn][maxn];//存放要求的第一类Stirling数
const long long mod=1e9+7;//取模

void init()//预处理
{
    memset(s,0,sizeof(s));
    s[1][1]=1;
    for(int i=2;i<=maxn-1;i++)
        for(int j=1;j<=i;j++)
    {
        s[i][j]=s[i-1][j-1]+(i-1)*s[i-1][j];
        if(s[i][j]>=mod)
            s[i][j]%=mod;
    }
}
时间: 2024-12-12 06:17:12

[组合数学] 第一类,第二类Stirling数,Bell数的相关文章

bell数

Bell数 Bell数的定义: 第n个Bell数表示集合元素个数为n的划分方案数,例如集合{1,2,3,-,n}. 即: B[0] = 1; 每一个Bell数都是第二类Stirling数的和,即: 第二类Stirling数 第二类Stirling数的定义: S(n,k)表示将n个物体划分成k个非空的不可辨别的(可以理解为盒子没有编号)集合的方法数. 很明显,每一个Bell数是对应的第二类Stirling数之和. Bell数的指数生成函数是: 版权声明:本文为博主原创文章,未经博主允许不得转载.

Bell(hdu4767+矩阵+中国剩余定理+bell数+Stirling数+欧几里德)

Bell Time Limit:3000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 4767 Description What? MMM is learning Combinatorics!? Looks like she is playing with the bell sequence now: bell[n] = number of ways to part

第二类Stirling数初探 By cellur925

上午noi.ac崩崩崩了,栽在组合数学上,虽说最后在辰哥&Chemist的指导下A掉了此题,也发现自己组合数学太弱了qwq. 在luogu上找题,结果找到了一个第二类斯特林数的题(还是双倍经验,逃.) 一.什么是第二类Stirling数 第二类斯特林数 S(n,k):把 n 个元素划分成 k 个集合的方案数.  这个问题说的实际一点,就比如说,有n个互异的小球,把他们放入m个盒子里,盒子里不允许为空的方案数.我们设s(i,j)表示放到i个小球,j个盒子的方案数. 那么对于每个小球,当前我们有两种

HDU 2643 Rank:第二类Stirling数

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2643 题意: 有n个个选手参赛,问排名有多少种情况(可以并列). 题解: 简化问题: 将n个不同的元素放到i个有差别的盒子中,情况数为P(n,i),求∑P(n,i) (1<=i<=n) 再简化: 将n个不同的元素放到i个无差别的盒子中,情况数为S(n,i),求∑( S(n,i)*i! ) (1<=i<=n) 哇这是第二类Stirling数 ( ̄▽ ̄)~* 递推式:s(n,k) = s(

poj 1671 Rhyme Schemes 第二类Stirling数

题意: 求s(n,0)+s(n,1)+...s(n,n),s(i,j)为第二类Stirling数. 分析: 有递推公式s(p,k)=(p-1)*s(p-1,k)+s(p-1,k-1) ,1<=k<=p-1. 代码: //poj 1671 //sep9 #include<iostream> using namespace std; double s[64][64]; double sum[64]; int main() { for(int i=0;i<=50;++i){ s[i

[ACM] FZU 1570 集合划分问题( 不同小球放入相同盒子,第二类Stirling数)

Problem Description n个元素的集合{1,2,...,n}可以划分若干个非空子集.例如,当n=4时,集合{1,2,3,4}可以划分为15个不同的非空子集如下: {{1},{2},{3},{4}}, {{1,2},{3},{4}}, {{1,3},{2},{4}}, {{1,4},{2},{3}}, {{2,3},{1},{4}}, {{2,4},{1},{3}}, {{3,4},{1},{2}}, {{1,2},{3,4}}, {{1,3},{2,4}}, {{1,4},{2,

恶补---bell数

定义 bell数即一个集合划分的数目 示例 前几项的bell数列为 1, 1, 2, 5, 15, 52, 203, 877, 4140, 21147, 115975 ,... 求值方法 1.bell数适合递推公式 2.每个贝尔数都是"第二类Stirling数"的和 3.用一下方法可以构造一个bell三角形(Aitken阵列或Peirce三角形) 1)第一行第一列是1 2)对于n>1,第n行第一列等于上一行的最后一个数 3)对于n>1,m>1,第n行第m列=第n行第m

lightoj1326_第二类Stirling

题目链接http://lightoj.com/volume_showproblem.php?problem=1326 1051 - Good or Bad    PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB A string is called bad if it has 3 vowels in a row, or 5 consonants in a row, or both. A strin

freemarker导出word——让表格数据行数 列数自动变化

行数.列数变化只需定义一个List<List<T>> freemarker遍历的话,只需要使用freemarker的标记性语言<#list report.qc_third_agentTable as  table2_tr>遍历即可,如图 实现的效果 freemarker导出word--让表格数据行数 列数自动变化,布布扣,bubuko.com