您的位置:首页 > 其它

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

2017-05-30 09:01 295 查看


Binomial Coeffcients



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


题目描写叙述



输入



输出



演示样例输入

3
1 1
10 2
954 723


演示样例输出

1
45
3557658


提示

来源

山东省第二届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

;

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;//直接输出
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: