@(算法學習)算法
(nk)=n!(n−k)!k!學習
計算二項式係數的問題在於,係數自己在int表示範圍內,可是計算用到的分子是階乘,這個是很大的數,會致使溢出的問題。ui
因此,比較好的計算方法是運用帕斯卡三角形總結的規律求解。atom
第一行表達的是:(00)=1spa
第二行表達的是:(10)=1,(11)=1
第三行表達的是:(20)=1,(21)=2,(22)=1翻譯
…code
更有趣的是,每個數是肩頭兩個數字之和。xml
運用的規律是:(nk)=(n−1k−1)+(n−1k)blog
,這個翻譯成中文很好理解。從n個東西中選取k個,在面對第k件東西時,有一個決策,這件不選或者選兩條路徑。選了第k件則從剩下的n-1件裏選k-1件便可。若是不選,就要從剩下的n-1件中選擇k件。圖片
這個思想在揹包問題中運用的尤爲普遍。揹包問題是動態規劃問題的一種模型,所以,也能夠側面反映動態規劃的思想。
#include <stdio.h> #define MAXN 100 long binomial_coefficient(int n, int m)// 從n中選擇m { int i,j; long bc[MAXN][MAXN]; //二項式係數表 for(i = 0; i <= n; i++) //帕斯卡三角每行第一個數全是1 { bc[i][0] = 1; } for(j = 0; j <= n; j++) // 帕斯卡三角每行最後一個數全是1 { bc[j][j] = 1; } for(i = 1; i <= n; i++) //狀態轉移方程 { for(j = 1; j < i; j++) { bc[i][j] = bc[i-1][j-1]+bc[i-1][j]; } } return bc[n][m]; } int main() { int n, m; while(scanf("%d%d",&n,&m)) { int res = binomial_coefficient(n,m); printf("Result = %d\n", res); } return 0; }