0-问题引入
有一个数组,里面是互不相同的\(n\)个元素,请在其中取出\(m(m\le n)\)个元素(无视顺序),求有几种取法?
I-定义
上题的答案表示为:\(C_n^m\)。
\(C_n^m\)是什么意思呢?
我们定义:\[C_n^m=\dfrac{n!}{m!(n\text{-}m)!}\]。
并统一定义,\(C_n^0=C^n_n=C^0_0=1\)。
II-性质
\[C_n^m=C_{(n-m)}^m(\texttt{互补性质})\]
\[C_n^m=C_{(n-1)}^{(m-1)}+C_{(n-1)}^{m}\]
\[\sum\limits_{k=0}^{n}C_n^k=2^n\]
III-应用
III-1 路径计数
在一个\((n\times m)\)的棋盘上\((1\le n,m\le 10^4)\),从左下角走到右上角,每次可以向右或上走一步,求方案总数。
【分析】
针对每种方案,一定有\(n\)次向上的操作,而共需走\(n+m\)次,因此在\(n+m\)中取\(n\)个即可。
【答案】\(C_{(n+m)}^n\)
III-2 方程的解
求方程\(x_1+x_2+...+x_n=k\)的非负整数解总数。
其中\(x_i>=y_i(y_i>=0)\)。
【分析】
首先,我们看一个小问题:
求方程\(x_1+x_2+x_3+x_4=10\)的正整数解总数。
其实,我们将\(10\)分解为\(10\)个\(1\),那么,我们就可以在这\(10\)个\(1\)中插\(3\)个“隔板”隔开这些1。
一组解:[1 1|1|1 1 1 1 1|1 1],此时x1=2,x2=1,x3=5,x4=2。
现在,我们的问题就是插隔板的方案数。
此处共有\(10-1\)处地方可以插隔板,答案显而易见为\(C_9^3\)
推广为\(n\)个未知数,总和为\(k\),那么答案为\(C_{(k-1)}^{(n-1)}\)
但如果是非负整数呢?
很简单,只要在\("1"\)中再插入\(n\)个一即可,即将\(k\)变为\(k+n\),再将其视为正整数解求即可。
原理:设\(a_i=x_i+1,b=k+n\)
那么则有:\(\sum\limits_{i=1}^{n}a_i =b\)。
而上面这个方程的正整数解数和\(x_1+x_2+...+x_n=k\)的非负整数解数是相同的。
所以我们用换元的思想解出了这个问题:\(C^{(n-1)}_{(k+n-1)}\)(隔板一直是\(n-1\)个)。
好了,我们重审本题。
其实就是比上面的问题多了一个限制。
转化方程为:\(x_1+x_2+...+x_n=k+\sum\limits_{i=1}^{n}y_i\)
解法同上,答案:\(\huge{C_{(k+\sum_{i=1}^{n}y_i+1)}^{(n-1)}}\)
IV-\(\texttt{</>Code}\)
vector<vector<int> > comb;
inline void Init_comb(const int &n,const int &mod)
{
register int i,j;
comb.resize(n+5);
for(i=0;i<=n;i++)comb[i].resize(i+5);
comb[0][0]=comb[1][0]=comb[1][1]=1%mod;
for(i=2;i<=n;i++)
{
comb[i][0]=1%mod;
for(j=1;j<=i;j++)
comb[i][j]=(comb[i-1][j-1]+comb[i-1][j])%mod;
}
}
Init_comb(n,mod):处理从(0,0)至(n,n)的组合数。
comb[i][j](i>=j):存放C(i,j)的值。