1. 程式人生 > >連乘r個整商,求組合的一個好策略

連乘r個整商,求組合的一個好策略

組合計算公式:C(n,m)=[n*(n-1)*······(n-m+1)]/m!

但是這個計算公式有個極大的缺陷,就是在不斷累積相乘的過程中會溢位(用long long也會很快溢位),思考下,能不能一邊做除法,一邊做乘法,這樣就可以避免結果增大的過快而產生溢位,用同類型變數可以算出更大的n和m,但是怎麼除呢?用浮點型變數肯定是不行的,這樣是個精確值,只能考慮整形變數。

乘法是先乘以大的數,除法是先除以小的數,推導可以發現,除法總是能夠整除的,這是因為兩個連續的整數必有一個是2的倍數,3個連續的整數必有一個是3的倍數······,考慮m個連續的整數,用m做模除,其中必有一個的餘數是0(鴿巢原理),即必有一個整數能被m整除。

下面給出程式碼:

//鴿巢原理,計算組合函式,n中取m,c(n,m)
long long C(int n,int m)
{
    long long c;
    if(n<m)
        c=0;
    else if(n==m||m==0)
        c=1;
    else{
        c=1;
        n=n-m+1;
        for(int i=1;i<=m;i++){
            c*=n++;
            c/=i;
        }
    }
    return c;
}