组合数

来源:互联网 发布:双三次插值算法 编辑:程序博客网 时间:2024/06/07 01:56

1、定义:从m个不同元素中,任取n(n≤m)个元素并成一组,叫做从m个不同元素中取出n个元素的一个组合;从m个不同元素中取出n(n≤m)个元素的所有组合的个数,叫做从m个不同元素中取出n个元素的组合数。

2、公式:在线性写法中被写作C(m,n)。c(m,n)=p(m,n)/n!=m!/((m-n)!*n!)

组合数性质

3、性质:

     (1):1.互补性质:组合数性质如上图所示:
即从m个不同元素中取出n个元素的组合数=从m个不同元素中取出(m-n)个元素的组合数。这个性质很容易理解。例如C(9,2)=C(9,7),即从9个元素里选择2个元素的方法与从9个元素里选择7个元素的方法是相等的。
        规定:C(m,0)=1

     (2):组合恒等式:

若表示在n个物品中选取m个物品,则如存在下述公式: C(n,m)= C(n,n-m)= C(n-1,m-1)+C(n-1,m)。

4、算法

第一种是比较简单的方法,时候数据表较小,分母能够计算出来的时候。

如求C(i,4),(4<=i<=maxn),maxn=10005;

    for(i=4;i<maxn;i++)//求组合数,即i个数里面选择4个数的选择的种类有几种。        node[i]=i*(i-1)*(i-2)*(i-3)/24;
第二种是数组求法,利用第二个性质。通常求较大的数,用递归会超时的。

二项式系数C(n, k)满足下面的要求:

C(n, 0) = C(n, n) = 1 for all n > 0;
C(n, k) = C(n − 1, k − 1) + C(n − 1, k) for all 0 < k < n.
题目要求根据给定的n和k(0 ≤ k ≤ n < 231, n > 0)计算C(n,k),典型的递归问题。
但是如果采用递归,当n的值比较大的时候,会堆栈益处。而上面的表达式应该有相应的公式。如果采用公式计算就会变的简单了。

#include<iostream>    using namespace std;    int main()  {      int n,k;      cin>>n>>k;        int *result = new int[n];         for(int i=1;i<=n;i++)      {          result[i] = 1;          for(int j=i-1;j>=1;j--)          {              result[j] = result[j-1]+result[j];          }          result[0] = 1;      }        cout<<result[k]<<endl;        return 0;  }  


原创粉丝点击