组合数与错排数求解方法探析

组合数:
我们都知道组合数C(m,n)的含义是从m个物品中选n个物品的方法种数,其冠以的数学求解表达式为:
C(m,n)=m!/(n!*(m-n)!); 这个公式是显而易见的,并不难证明。
但是某些题目中利用阶乘求其组合数,会浪费很多的时间和空间,可能会出现TLE,WA。因此,我们不得不寻求一些技巧,更加快捷的求出组合数。
现将常用的球求组合数C(m,n)总结如下

    1)
        int a[1000]
         a[0]=1;
         for(int i=1;i<=m;i++)
              for(int j=i;j>=1;j--)
                   a[j]+=a[j-1]; 
       注意:此方法只有当两重循环完成时,a[n]才能表示C(m,n),中间值不能表示C(m,n).
                 此规律可有杨辉三角中的规律得来。
    2)数组保存n!
         int a[max];
         a[0]=1;
         for(int i=1;i<max;i++)
                a[i]=i*a[i-1];
        此时a[i]保存了i!,则C(m,n)=a[m]/a[n]/a[m-n].
  • 错排数:
    由容斥原理很容易得到错排公式为:
    S[n]=n!(1-1/1!+1/2!-1/3!+1/4!……….(-1)^n*1/n!)
    而且 错排数相邻两项递推S[n]=n*S[n-1]+(-1)^n;
    值得注意的是
    还有第二种递推式:
    S[n]=(n-1)*(S[n-1]+S[n-2])
    因此可以有两种打表方式:
               a[0]=0;a[1]=0;
           for(int i=0;i<max;i++)
              a[i]=i*a[i-1]+(-1)^i
               或:
       for(int i=2;i<max;i++)
             a[i]=(i-1)*(a[i-1]+a[i-2]);

转载于:https://www.cnblogs.com/Wu-Shi/p/5410076.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值