求二項式因子的演算法

來源:互聯網
上載者:User

組合數C(n, k)的求法:

 

 

1. 浮點數迭代法

 

缺點: 當數比較大的時候, 可能結構不夠精確.

使用公式

 

 

#include <iostream><br />using namespace std;<br />int main()<br />{<br />long double n, k, ans;<br />while(cin >> n >> k && (n || k)){<br />ans = 1;<br />if(k > n/2)<br />k = n - k;<br />for(long double i=0; i<k; i++)<br />ans *= (n-i)/(k-i);<br />cout.precision(0);<br />cout << fixed << ans << endl;<br />}<br />}

 

或:

 

#include <iostream><br />using namespace std;<br />__int64 c(__int64 n, __int64 k)<br />{<br />if(k == 0 || n==k)<br />return 1;<br />else<br />return c(n-1, k-1)*n/k;<br />}<br />int main()<br />{<br />__int64 n,k;<br />while (scanf("%I64d%I64d", &n, &k)!=EOF && (n+k))<br />{<br />if(2*k > n)<br />k = n-k;<br />printf("%I64d/n", c(n,k));<br />}<br />return 0;<br />}

 

 

 

2. 動態規劃法

 

缺點: 對空間有較大的要求.

具體為:

 

n
0 1              
1 1 1            
2 1 2 1          
3 1 3 3 1        
4 1 4 6 4 1      
5 1 5 10 10 5 1    
6 1 6 15 20 15 6 1  
7 1 7 21 35 35 21 7 1

 

#define MAXSIZE 10000<br />long cnr(int n, int r)<br />{<br /> long c[MAXSIZE];<br /> int i, j;<br /> for (i = 0; i <= r; i++)<br /> c[i] = 1;<br /> for (i = 1; i <= n-r; i++)<br /> for (j = 1; j <= r; j++)<br /> c[j] += c[j-1];<br /> return c[r];<br />}

 

 

.快速演算法

 

還有一種快速演算法, 在<<C語言名題精選百則>>上有所敘述.

下面展示一道題:

 

pku 3219 Binomial Coefficients

 

求C(n, k)的最後一位是0,還是1(即結果是奇數還是偶數).

這道題採用一步一步的最佳化的示範方法.

可以注意到k<=n<2^31, k,n如此之大, 肯定不能用上面的方法, 也不必用, 因為他只需要知道結構是奇數還是偶數.

那判斷C(n,k) = A(n,k)/A(k,k)的分母分子個含有2這個因子的個數的多少,相減即可.

 

#include <iostream><br />using namespace std;<br />//方法一:<br />//利用c(n, k) = c(n-1,k-1)+c(n-1,k)的原始方法<br />//int c(int n, int k)<br />//{<br />//if(k==0 || n==k)<br />//return 1;<br />//else<br />//return (c(n-1,k-1)+c(n-1,k))&1;<br />//}<br />//奇(1)*奇(1)=奇(1), 偶(0)*奇(1)=偶(0), 偶(0)*偶(0)=偶(0) [求積為&]<br />//奇(1)+奇(1)=偶(0), 偶(0)+奇(1)=奇(1), 偶(0)+偶(0)=偶(0) [求和為^]<br />//方法二:<br />//利用c(n, k) = ∑c(k,i)*c(n-k, i) (i∈[0, k], 且n>=2*k)的快速求組合數演算法<br />//int c(int n, int k)<br />//{<br />//if(k == 0 || k == n)<br />//return 1;<br />//<br />//if(2*k > n)<br />//k = n-k;<br />//int ret = 1;<br />//for(int i = 1; i <= k; ++i)<br />//ret ^= c(k, i)&c(n-k, i);<br />//return ret;<br />//}<br />//方法三:<br />//利用C(n,k) = A(n,k)/A(k,k), 求分子和分母因子2的個數的方法.<br />int cal(int n)<br />{<br />int cnt = 0;<br />int c = 2;<br />while(n)<br />{<br />n >>= 1;<br />cnt += n;<br />}<br />return cnt;<br />}<br />int main()<br />{<br />unsigned int n, k;<br />while(scanf("%d%d", &n, &k) != EOF)<br />{<br />if(k == 0 || n == k)<br />{<br />printf("1/n");<br />continue;<br />}<br />if(2*k > n)<br />k = n-k;<br />int cnt1 = cal(n);<br />int cnt2 = cal(n-k);<br />int cnt3 = cal(k);<br />printf("%d/n", (cnt1-cnt2)>cnt3?0:1);<br />}<br />return 0;<br />}

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.