快速计算C(n,r)

在网上见的,引用出处为:http://blog.csdn.net/alexingcool/article/details/7997599

可以在logn内计算出,但是容易溢出。

[cpp] view plain copy 
01.#include <iostream>  
02.#include <iterator>  
03.#include <algorithm>  
04.  
05.using namespace std;  
06.  
07.#define MAXSIZE 100  
08.unsigned long answer[MAXSIZE];  
09.  
10.unsigned long long int power(unsigned long base, unsigned long exp)  
11.{  
12.    unsigned long long int result = 1;  
13.    while (exp)  
14.    {  
15.        if (exp & 0x01)  
16.            result *= base;  
17.        base *= base;  
18.        exp >>= 1;  
19.    }  
20.  
21.    return result;  
22.}  
23.  
24.void cnr(unsigned long n, unsigned long *answer)  
25.{  
26.    unsigned long long int x = (1 << n) + 1;  
27.    unsigned long long int mask = (1 << n) - 1;  
28.    unsigned long long int result;  
29.  
30.    result = power(x, n);  
31.    for (unsigned long i = 0; i <= n; i++, result >>= n)  
32.    {  
33.        cout << result << endl;  
34.        answer[i] = result & mask;  
35.        cout << "answer[" << i << "] = " << answer[i] << endl;      
36.    }  
37.}  
38.  
39.void main()  
40.{  
41.    int number = 4;  
42.    cnr(number, answer);  
43.    copy(answer, answer + number, ostream_iterator<int>(cout, " "));  
44.} 

当然,可以用动归,慢点,n2
利用公式C(n,r)=C(n-1,r-1)+C(n-1,r)来化简求解:

01.#include <iostream>  
02.  
03.using namespace std;  
04.  
05.#define MAXSIZE 100  
06.  
07.unsigned long cnr(int n, int r)  
08.{  
09.    unsigned long c[MAXSIZE];  
10.    int i, j;  
11.    for (i = 0; i <= r; i++)  
12.        c[i] = 1;  
13.    for (i = 1; i <= n - r; i++)  
14.        for (j = 1; j <= r; j++)  
15.            c[j] += c[j - 1];  
16.    return c[r];  
17.}  
18.  
19.void main()  
20.{  
21.    int result = cnr(10, 2);  
22.    cout << "result = " << result << endl;  
23.}  

还可以用质因数分解,不易溢出。

原文地址:https://www.cnblogs.com/gryzy/p/6015466.html