[2011山東ACM省賽] Binomial Coeffcients(求組合數)
阿新 • • 發佈:2017-05-30
取余 cor memory -s sin mage pad ruby end
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[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(求組合數)