首先給出楊輝三角(也叫帕斯卡三角形數陣,但我們中國比他早300年)如上圖,可以發現三角兩邊都是1,而中間的數都是上面兩個數的和,滿足dp[i][j]=dp[i-1][j]+dp[i-1][j-1]這樣的遞推關係。
然後再來看(a+b)n,將它展開會得到:
(a+b)0=1
(a+b)1=a+b
(a+b)2=a2+2ab+b2
(a+b)3=a3+3a2b+3ab2+b3
可以發現每項前面的係數和楊輝三角中的數字很吻合。我們再來看二項式定理:
(a+b)n=∑k=0nCnkan−kbk
那麼二項式定理表示的是什麼意義呢,首先這相當於n個(a+b)相乘,那麼在每個括號裏肯定要選出a或者b來和另外幾個括號中的a或者b來相乘,那麼有多少種情況呢,我們假設在這n個括號中選擇了k個b,那麼剩下的就是n-k個a了,情況總數是Cnk或者Cnn−k根據組合數的性質,這兩個數是相等的。
然後我們就可以證明下面這個等式:
Cnm=Cn−1m−1+Cn−1m
這個可以這麼理解一下:
在n件物品中選出m件物品有多少種可能性?
答案是:從n-1件中選出m-1件的可能性+從n-1件中選出m件的可能性。(第m件物品可選可不選)
這和上面楊輝三角形有非常密切的聯繫,和其所滿足的遞推式也異常相似。(證明好長,明白就好了。。)
通過這個等式我們可以推出所有的組合數。
for(int i=1;i<=1000;i++)
{
c[i][0]=1;c[i][i]=1;
for(int j=1;j<i;j++)
c[i][j]=c[i-1][j]+c[i-1][j-1];
}
很明顯時間複雜度O(n2)
但還有一個可以求非常小範圍組合數的等式:
Cnk=kn−k+1Cnk−1
下面是證明過程:
Cnk=k!(n−k)!n!
=k(k−1)!n(n−1)(n−2)....(n−k+1)
=kn−k+1(k−1)!(n−k+1)!n!(上下同乘(n−k+1)!)
=kn−k+1Cnk−1
int n;
cin>>n;
c[0]=1;
for(int i=1;i<=n;i++) c[i]=c[i-1]*(n-i+1)/i;\\先乘後除