首页 > 代码库 > [2011山东ACM省赛] Binomial Coeffcients(求组合数)

[2011山东ACM省赛] Binomial Coeffcients(求组合数)

Binomial Coeffcients

nid=24#time" style="padding-bottom:0px; margin:0px; padding-left:0px; padding-right:0px; color:rgb(83,113,197); text-decoration:none; padding-top:0px">

Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^

题目描写叙述

 技术分享

输入

 技术分享

输出

技术分享 

演示样例输入

31 110 2954 723

演示样例输出

1453557658

提示

 

来源

山东省第二届ACM大学生程序设计竞赛

 

解题思路:

这道题坑死我了。

。本来非常easy的一道题。却怎么也做不正确。。

就是求组合数。结果对10000003取模。一開始对c(m,n)是用公式直接求的。可是计算过程中涉及到取余,不能用下面代码写:

int c(int m,int n){    int sum=1;    for(int i=1;i<=n;i++)    {        sum=sum*(m--)/i;        sum%=mod;    }    return sum;}


这个代码是错误的。

比方 C(9,3)对5取余  上面的代码 的计算过程是这种   sum=sum*9/1   sum=9  sum%5=4     4*8/2=16   16%5=1  1*7/3 =?这下问题出来了把。

不能整除。这个计算过程中不能进行取模运算,可是直接算又越界。后来又想到求组合数分子分母进行约分以后再计算。測试数据对,可是可怜的超时。

哎。。因此仅仅能用组合递推得来算,由于每递推到一个数,假设它大于mod,就取模,这种一个组合式是正确的,由于题意就这样说得。因此由递推得到的每个组合式都是正确的,并且不会越界。

另外须要注意的是: c[0][0]=1 这个题少了这一句就WA

代码:

#include <iostream>#include <string.h>using namespace std;const int mod=10000003;const int N=1002;int c[N][N];void init()//递推打表{    memset(c,0,sizeof(c));    c[0][0]=c[1][0]=c[1][1]=1;    for(int i=2;i<N;i++)    {        c[i][i]=c[i][0]=1;        for(int j=0;j<i;j++)        {            c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;//不会越界        }    }}int main(){    init();    int k;cin>>k;    int a,b;    while(k--)    {        cin>>a>>b;        cout<<c[a][b]<<endl;//直接输出    }}


 

[2011山东ACM省赛] Binomial Coeffcients(求组合数)