n个有区别的球放到m个相同的盒子中,要求无一空盒,
其不同的方案数用S(n,m)表示,称为第二类Stirling数。
下面就让我们根据定义来推导带两个参数的递推关系——第二类Stirling数。解:设有n个不同的球,分别用b1,b2,……bn表示。从中取出一个球bn,bn的放法有以下两种:
①bn独自占一个盒子;那么剩下的球只能放在m-1个盒子中,方案数为S2(n-1,m-1);
②bn与别的球共占一个盒子;那么可以事先将b1,b2,……bn-1这n-1个球放入m个盒子中,然后再将球bn可以放入其中一个盒子中,方案数为mS2(n-1,m)。
综合以上两种情况,可以得出第二类Stirling数定理:
【定理】S2(n,m)=mS2(n-1,m)+S2(n-1,m-1) (n>1,m1)
边界条件可以由定义2推导出:
S2(n,0)=0;S2(n,1)=1;S2(n,n)=1;S2(n,k)=0(k>n)。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>//无空盘子
using namespace std;
int f(int m,int n)
{
if(n==0)return 0;//没有盘子
if(n==1)return 1;//只有一个盘子
if(m==n)return 1;
if(m<n)return 0;//不能塞满
return n*f(m-1,n)+f(m-1,n-1);//先把m-1个放到n个盘子中,然后再把第一个放到剩下的盘子中,加上第一个苹果占一个盘子,剩下的m-1个占n-1个盘子
}
int main()
{
int n,m;
cin>>m>>n;
cout<<f(m,n);
return 0;
}
n个有区别的球放到m个相同的盒子中,要求可以有空盒
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;
int f(int m,int n)
{
if(m<n)n=m;
if(m==0)return 1;//没有苹果
if(n==1)return 1;//只有一个盘子
return f(m,n-1)+f(m-n,n);//m个苹果放到n-1个盘子里加上
//每个盘子先放上一个,剩下的再放到n个盘子里
}
int main()
{
int n,m;
cin>>m>>n;
cout<<f(m,n);
return 0;
}