对于排列组合求组合数如果直接求值数据范围太大,时间太长。
其实排列组合还是挺有规律的,例如下面的
(1,1) (1,2) (1,3) (1,4) (1,5) (1,6)
1 2 3 4 5 6
(2,2) (2,3) (2,4) (2,5) (2,6)
1 3 6 10 15
(3,3) (3,4) (3,5) (3,6)
1 4 10 20
(4,4) (4,5) (4,6)
1 5 15
(5,5) (5,6)
1 6
(6,6)
1
因为具有对称性,我只列了一半,高中书本里介绍过杨辉三角,其实很简单,就是c(n,m)=c(n,m-1)+c(n-1,m-1),对应到上幅图中就是:某一个 等于 这个的左边的 加上 这个左边的上边的。即C(2,3) = C(2,2)+C(1,2)
void init()
{
c[0][0]=1;
for (int i=1;i<=maxn;++i)
{
c[i][0]=c[i][i]=1;
for (int j=1;j<i;++j)
{
c[i][j]=c[i-1][j]+c[i-1][j-1];
//cout<<c[i][j]<<" ";
}
//cout<<endl;
}
那么我们先把第一层算出来,然后递推第二层,然后递推。这种方法的优点是一次就把所有的求出来了,而且中间可以进行取模运算。