zoukankan      html  css  js  c++  java
  • 组合计数 && Stirling数

    参考:

    http://blog.csdn.net/qwb492859377/article/details/50654627

    http://blog.csdn.net/acdreamers/article/details/8521134

    http://blog.csdn.net/sr_19930829/article/details/40888349

    球,盒子都可以分成是否不能区分,和能区分,还能分成是否能有空箱子,所以一共是8种情况,我们现在来一一讨论。

    1.球同,盒不同,无空箱

    C(n-1,m-1), n>=m
    0, n<m

    使用插板法:n个球中间有n-1个间隙,现在要分成m个盒子,而且不能有空箱子,所以只要在n-1个间隙选出m-1个间隙即可

    2.球同,盒不同,允许空箱

    C(n+m-1,m-1)

    我们在第1类情况下继续讨论,我们可以先假设m个盒子里都放好了1个球,所以说白了就是,现在有m+n个相同的球,要放入m个不同的箱子,没有空箱。也就是第1种情况

    3.球不同,盒相同,无空箱

    第二类斯特林数dp[n][m]
    dp[n][m]=m*dp[n-1][m]+dp[n-1][m-1],1<=m<n
    dp[k][k]=1,k>=0
    dp[k][0]=0,k>=1
    0,n<m

    这种情况就是第二类斯特林数,我们来理解一下这个转移方程。

    对于第n个球,如果前面的n-1个球已经放在了m个箱子里,那么现在第n个球放在哪个箱子都是可以的,所以m*dp[n-1][m];

    如果前n-1个球已经放在了m-1个箱子里,那么现在第n个球必须要新开一个箱子来存放,所以dp[n-1][m-1]

    其他的都没法转移过来

    4.球不同,盒相同,允许空箱

    sigma dp[n][i],0<=i<=m,dp[n][m]为情况3的第二类斯特林数

    这种情况就是在第3种情况的前提下,去枚举使用的箱子的个数

    5.球不同,盒不同,无空箱

    dp[n][m]*fact[m],dp[n][m]为情况3的第二类斯特林数,fact[m]为m的阶乘

    因为球是不同的,所以dp[n][m]得到的盒子相同的情况,只要再给盒子定义顺序,就等于现在的答案了

    6.球不同,盒不同,允许空箱

    power(m,n) 表示m的n次方

    每个球都有m种选择,所以就等于m^n

    7.球同,盒同,允许空箱

    dp[n][m]=dp[n][m-1]+dp[n-m][m], n>=m
    dp[n][m]=dp[n][m-1], n<m
    边界dp[k][1]=1,dp[1][k]=1,dp[0][k]=1

    现在有n个球,和m个箱子,我可以选择在所有箱子里面都放上1个球,也可以不选择这个操作。

    如果选择了这个操作,那么就从dp[n-m][m]转移过来

    如果没有选择这个操作,那么就从dp[n][m-1]转移过来

    8.球同,盒同,无空箱

    dp[n-m][m],dp同第7种情况,n>=m
    0, n<m

    因为要求无空箱,我们先在每个箱子里面放1个球,然后还剩下n-m个球了,再根据情况7答案就出来了

    第一类Stirling数 s(p,k)

        

    s(p,k)的一个的组合学解释是:将p个物体排成k个非空循环排列的方法数。

    s(p,k)的递推公式: s(p,k)=(p-1)*s(p-1,k)+s(p-1,k-1) ,1<=k<=p-1

    边界条件:s(p,0)=0 ,p>=1  s(p,p)=1  ,p>=0

     

    递推关系的说明:

    考虑第p个物品,p可以单独构成一个非空循环排列,这样前p-1种物品构成k-1个非空循环排列,方法数为s(p-1,k-1);

    也可以前p-1种物品构成k个非空循环排列,而第p个物品插入第i个物品的左边,这有(p-1)*s(p-1,k)种方法。

     

    第二类Stirling数 S(p,k)

       

    S(p,k)的一个组合学解释是:将p个物体划分成k个非空的不可辨别的(可以理解为盒子没有编号)集合的方法数。

    k!S(p,k)是把p个人分进k间有差别(如:被标有房号)的房间(无空房)的方法数。

       

    S(p,k)的递推公式是:S(p,k)=k*S(p-1,k)+S(p-1,k-1) ,1<= k<=p-1

    边界条件:S(p,p)=1 ,p>=0    S(p,0)=0 ,p>=1

      

    递推关系的说明:

    考虑第p个物品,p可以单独构成一个非空集合,此时前p-1个物品构成k-1个非空的不可辨别的集合,方法数为S(p-1,k-1);

    可以前p-1种物品构成k个非空的不可辨别的集合,第p个物品放入任意一个中,这样有k*S(p-1,k)种方法。

      

    第一类斯特林数和第二类斯特林数有相同的初始条件,但递推关系不同。

    //第二类Stirling数
    long long s[maxn+10][maxn+10];//存放要求的Stirling数  
    const long long mod=1e9+7;  
    void get_s2()
    {  
        memset(s,0,sizeof(s));  
        s[1][1]=1;  
        for(int i=2;i<=maxn;i++){  
            for(int j=1;j<=i;j++){  
                s[i][j]=s[i-1][j-1]+j*s[i-1][j];
                //s[i][j]=(s[i-1][j-1]+j*s[i-1][j]%mod)%mod; //如果需要取模
            }
        }
    }
    //第一类stirling数
    void get_s1()  
    {  
        memset(s,0,sizeof(s));  
        s[1][1]=1;  
        for(int i=2;i<=maxn;i++){  
            for(int j=1;j<=i;j++){  
                s[i][j]=s[i-1][j-1]+(i-1)*s[i-1][j];  
                //s[i][j]=(s[i-1][j-1]+(i-1)*s[i-1][j]%mod)%mod;
            }
        }
    }  
  • 相关阅读:
    Android开发学习笔记-关于Android的消息推送以及前后台切换
    C#文件操作工具类
    c#取得应用程序根目录
    Visual Studio 2012中使用GitHub
    C#邮件发送
    jquery判断某个属性是否存在 hasAttr
    js 如何让两个等长的数组产生键值对关系
    js判断一个元素是否在数组中
    日期控件
    react 生命周期函数的一些心得体会
  • 原文地址:https://www.cnblogs.com/--ZHIYUAN/p/7384657.html
Copyright © 2011-2022 走看看