组合数的求法
今天是国庆节,没有出去,因为之前一直都在学习数据结构的东西,把图论的东西忘的差不多,七天乐,乐图论。今天早上电脑无缘无故开不了机,没办法我把硬盘拆了又重装了一遍。昨晚看到个给出一棵K叉树的前序跟后序遍历,让算一下这个树一共有多少种形态。里面涉及到一点求组合数的知识,我把他弄上来,免的自己以后忘记了。(因为渐渐的需要记的东西实在是太多了,我就当这里是我的笔记本吧。)同时也希望能帮到对这个地方有点模糊的初学者。
我这里有三种求组合数的方法,我一一来给大家解释。
第一种是递归构造组合数:
View Code
int f(int m,int n) { if(n==0) return 1; else if(n==1) return m; else if(n>m/2) return f(m,m-n); else return f(m-1,n)+f(m-1,n-1); }
这种方法由于是递归,当m达到20的时候就没办法出答案了。我是搜索盲,这个也让我记住了搜索层数的限制。当然如果空间小的话,层数也有可能加深。这个代码也可以在搜索的同时加个记忆化,就是把算过的结果记录下来。这样的话就跟第二种方法有点像了。
第二种方法n^2打表:
View Code
int c[maxn][maxn]; void ComputeC() { memset(c,0,sizeof(c)); for(int i=0; i<N; i++) { c[i][0] = 1; } for(int i=1; i<N; i++) { for(int j=i; j<N; j++) { c[i][j] = c[i-1][j-1]+c[i][j-1]; } } }
很多同学,我想应该会这么做的。
第三种方法是第二种方法的不保存版:
View Code
//c(m,cnt) int zuhe(int cnt) { int count=1; for(int i=1;i<=cnt;i++) { count*=m-i+1; count/=i; } return count; }
如果不想保存就用这种的。当然如果这个函数在程序里面调用太多次,能保存的话还是保存的好。
大概就这样了,我也是初学者,跟大家一起进步吧。加油!!!
勸君惜取少年時&莫待無花空折枝
posted on 2012-10-01 14:21 Raining Days 阅读(600) 评论(2) 编辑 收藏 举报