组合数

Posted peppa

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了组合数相关的知识,希望对你有一定的参考价值。

【题目背景】

我们知道,一块泥坑里有一只佩奇和一只乔治,通过1+1=2,得到了这块泥坑里总共有两只猪的结论。

【题目描述】
求出C(n,r)的最后十位,其中0<r≤n≤30000,输出时不足十位数也按十位输出,此
时高位用0 表示。C(n,r)=n×(n-1)×……×(n-r+1)/(1×2×3×……×r)。
输入数据为两个以空格隔开的自然数n,r。
【输入】
一行两个整数
【输出】
一行,10 位数字
2
【样例输入】
5 2
【样例输出】
0000000010

问题分析:首先,连续r个自然数的积一定能够被r!整除,因为将式子展开,我们会发现r!(分母)中的每一项都会和分子中的某些数约分,最终分母便变成了1。因此,C(n,r)的值一定是一个自然数。

其次,本题是可以避免除法的,方法之一就是约分。 将分子分母中出现的质i分解成若干个质数的乘积,记录这若干个质数当中,每个数出现的次数(用数组),例如,把72分解成2*2*2*3*3,则a[2]=3,a[3]=2。3为2在72中的重数,2为3在72中的重数。然后,对于分母中出现了质因子,则a[质因子]--,若出现在分子中,则a[质因子]++最后,将每个质因子按其重数连乘即可。

#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cstdlib>
using namespace std;
int a[30000],t,i,j,n,r,s;
int b[21]; 
const int maxn=20;
void divide(int n)
{
    int m;
    m=2;
    while (m*m<=n) 
    {
        while (n%m==0&&n!=0) 
        {
            n=n/m;
            a[m]--;//m的重数个数减一
        }
        m++;
    }
    a[n]--;
}
 
void times(int n)  
{
    int m;
    m=2;              
    while (m*m<=n)
    {
        while(n%m==0&&n!=0)
        {
            n=n/m;
            a[m]++;//m的重数个数加1 
        }
        m++;
    }
    a[n]++;
}
 
void add(int d)//质因子与重数连乘 ,数组b储存结果的每一位数字
{
    int dd,i,t;
    i=1; j=0;     
    while (i<=maxn)     
    {
        t=b[i]*d+j;     
        b[i]=t%10;
        j=t/10;
        i++;
    }
    i=1; j=0;
    while(i<=maxn)      
    {
        t=b[i]+j;
        b[i]=t%10;
        j=t/10;
        i++;
    }
}
 
int main()
{
    cin>>n>>r;
    memset(a,0,sizeof(a));
    i=n-r+1;
    j=r;
    do
    {
        if (i<=n)
        {
            times(i); i++;    
        }
        if (j>1)
        {
            divide(j); j--;
        }
    }while(i<=n||j>1);
     
    memset(b,0,sizeof(b));
    b[1]=1;
    for (i=2;i<=29999;i++)
    {
        while (a[i]>0)  
        {
            add(i);
            a[i]--;
        }
    }
    for (j=10; j>=1;j--)//输出组合数的末十位
    cout<<b[j];
    cout<<endl;
    return 0;
}

 

以上是关于组合数的主要内容,如果未能解决你的问题,请参考以下文章

如何组合绑定片段而不将它们包装在 XML 文字中

48个值得掌握的JavaScript代码片段(上)

精心收集的 48 个 JavaScript 代码片段,仅需 30 秒就可理解!(转载)

片段组合在 Relay 中是如何工作的?

如何将片段中的 ListView 对象的数据传递给 Activity?

为 memcached 和 Rails 组合片段和对象缓存的最佳方式