题目描述: ios
Description 函数
现有r个互不相同的盒子和n个互不相同的球,要将这n个球放入r个盒子中,且不容许有空盒子。问有多少种方法?
例如:有2个不一样的盒子(分别编为1号和2号)和3个不一样的球(分别编为一、二、3号),则有6种不一样的方法:
spa
Input code
两个整数,n和r,中间用空格分隔。(0≤n, r≤10) ip
Output 数学
仅一行,一个整数(保证在长整型范围内)。表示n个球放入r个盒子的方法。 it
Sample Input io
3 2
Sample Output stream
6
思路:一道数学问题,与求包含n个元素的集合划分为正好k个非空不相交子集的方法的数目十分类似,因此用Stirling数来解决,
递推公式为:
S(n,k)=0; (n<k||k=0) S(n,n) = S(n,1) = 1,
S(n,k) = S(n-1,k-1) + kS(n-1,k).
固然这道题还有一点不一样之处就是每一个盒子又有区别,因此到最后求出Stirling数后,还要乘上k(盒子数)的全排列。
如下为记忆化搜索和递推两种思路的源代码:
记忆化搜索源程序:#include <iostream> #include <cstdio> using namespace std; int n,k,sum=0; void init() { scanf("%d %d",&n,&k); } int work(int n,int k) { if(k>n) return(0); else if(k==1||k==n) return(1); else return(work(n-1,k-1)+work(n-1,k)*k); } int jiecheng(int k) { int i; int zong=1; for(i=k;i>0;i--) zong*=i; return(zong); } void solve() { if(k==1) printf("%d",1); else if(k==n) printf("%d",jiecheng(k)); else if(k>n) printf("%d",0); else if(k==0) printf("%d",0); //中间加了好多特殊状况判断,感受有点没有必要~~ else { sum=work(n,k); printf("%d",sum*jiecheng(k)); } } int main() { init(); solve(); }递推源代码:#include <iostream> #include <cstdio> using namespace std; int a[11][11]; int n,k; void init() { freopen("1257.in","r",stdin); scanf("%d %d",&n,&k); a[0][0]=1; } int jiecheng(int k) { int i; int zong=1; for(i=k;i>0;i--) zong*=i; return(zong); } void solve() { int i,j; for(i=1;i<=k;i++) for(j=1;j<=n;j++) a[j][i]=a[j-1][i-1]+(a[j-1][i]*i); freopen("1257.out","w",stdout); printf("%d",a[n][k]*jiecheng(k)); } int main() { init(); solve(); }反思:没有什么注释的,只要细心便可。斯特林数
斯特林数出如今许多组合枚举问题中. 对第一类斯特林数 StirlingS1[n,m], 给出恰包含 m 个圈的 n 个元素 的排列数目. 斯特林数知足母函数关系 . 注意某些 的定义与 Mathematica 中的不一样,差异在于因子 . 第二类斯特林数 StirlingS2[n,m]给出把 n 个可区分小球分配到m个不可区分的的盒子,且盒子没有空盒子的方法的数量. 它们知足关系 . 划分函数 PartitionsP[n]给出把整数 n 写为正整数的和,不考虑顺序的方法的数目. PartitionsQ[n]给出把整数 n 写为正整数的和,而且和中的整数是互不相同的 写法的数目设S(p,k)是斯特林数S(p,k)的一个组合学解释是:将p个物体划分红k个非空的不可辨别的(能够理解为盒子没有编号)集合的方法数。S(p,k)的递推公式是:S(p,k) = k*S(p-1,k) + S(p-1,k-1) ,1<= k <=p-1边界条件:S(p,p) = 1 ,p>=0S(p,0) = 0 ,p>=1递推关系的说明:考虑第p个物品,p能够单独构成一个非空集合,此时前p-1个物品构成k-1个非空的不可辨别的集合,方法数为S(p-1,k-1);也能够前p-1种物品构成k个非空的不可辨别的集合,第p个物品放入任意一个中,这样有k*S(p-1,k)种方法。第一类斯特林数和第二类斯特林数有相同的初始条件,但递推关系不一样。引用Brualdi《组合数学》里的一段注释 “对于熟悉线性代数的读者,解释以下:具备(好比)实系数,最多为p次的那些各项式造成一个p+1维的向量空间。组1,n,n^2,...。n^p和组 A(n, 0),A(n,1),A(n,2),... ,A(n,p)都是该空间的基。第一类Stirling数和第二类Stirling数告诉咱们如何用其中的一组基表示另外一组基。”