盒子与球解题报告
2013-09-08 00:00
134 查看
题目描述:
Description
现有r个互不相同的盒子和n个互不相同的球,要将这n个球放入r个盒子中,且不允许有空盒子。问有多少种方法?
例如:有2个不同的盒子(分别编为1号和2号)和3个不同的球(分别编为1、2、3号),则有6种不同的方法:
Input
两个整数,n和r,中间用空格分隔。(0≤n,r≤10)
Output
仅一行,一个整数(保证在长整型范围内)。表示n个球放入r个盒子的方法。
SampleInput
SampleOutput
递推源代码:
#include<iostream>
#include<cstdio>
usingnamespacestd;
inta[11][11];
intn,k;
voidinit()
{
freopen("1257.in","r",stdin);
scanf("%d%d",&n,&k);
a[0][0]=1;
}
intjiecheng(intk)
{
inti;
intzong=1;
for(i=k;i>0;i--)
zong*=i;
return(zong);
}
voidsolve()
{
inti,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
[k]*jiecheng(k));
}
intmain()
{
init();
solve();
}
反思:没有什么注释的,只要细心即可。
给出把整数n写为正整数的和,不考虑顺序的方法的数目.PartitionsQ
给出把整数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>=0
S(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数告诉我们如何用其中的一组基表示另一组基。”
Description
现有r个互不相同的盒子和n个互不相同的球,要将这n个球放入r个盒子中,且不允许有空盒子。问有多少种方法?
例如:有2个不同的盒子(分别编为1号和2号)和3个不同的球(分别编为1、2、3号),则有6种不同的方法:
Input
两个整数,n和r,中间用空格分隔。(0≤n,r≤10)
Output
仅一行,一个整数(保证在长整型范围内)。表示n个球放入r个盒子的方法。
SampleInput
32
SampleOutput
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> usingnamespacestd; intn,k,sum=0; voidinit() { scanf("%d%d",&n,&k); } intwork(intn,intk) { if(k>n) return(0); elseif(k==1||k==n) return(1); elsereturn(work(n-1,k-1)+work(n-1,k)*k); } intjiecheng(intk) { inti; intzong=1; for(i=k;i>0;i--) zong*=i; return(zong); } voidsolve() { if(k==1) printf("%d",1); elseif(k==n) printf("%d",jiecheng(k)); elseif(k>n) printf("%d",0); elseif(k==0) printf("%d",0);//中间加了好多特殊情况判断,感觉有点没有必要~~ else { sum=work(n,k); printf("%d",sum*jiecheng(k)); } } intmain() { init(); solve(); }
#include<cstdio>
usingnamespacestd;
inta[11][11];
intn,k;
voidinit()
{
freopen("1257.in","r",stdin);
scanf("%d%d",&n,&k);
a[0][0]=1;
}
intjiecheng(intk)
{
inti;
intzong=1;
for(i=k;i>0;i--)
zong*=i;
return(zong);
}
voidsolve()
{
inti,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
[k]*jiecheng(k));
}
intmain()
{
init();
solve();
}
斯特林数
斯特林数出现在许多组合枚举问题中.对第一类斯特林数StirlingS1[n,m],给出恰包含m个圈的n个元素的排列数目.斯特林数满足母函数关系.注意某些的定义与Mathematica中的不同,差别在于因子.第二类斯特林数StirlingS2[n,m]给出把n个可区分小球分配到m个不可区分的的盒子,且盒子没有空盒子的方法的数量.它们满足关系.划分函数PartitionsP给出把整数n写为正整数的和,不考虑顺序的方法的数目.PartitionsQ
给出把整数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>=0
S(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数告诉我们如何用其中的一组基表示另一组基。”
相关文章推荐
- 【解题报告】uva103_Stacking Boxes(堆砌盒子, dp)
- 盒子游戏解题报告
- vijos1060 盒子(重庆一中高2018级信息学竞赛测验7) 解题报告
- pku 3750 小孩报数问题 解题报告
- 1586. Threeprime Numbers 解题报告 URAL
- 北京航空航天大学2014第三次上机解题报告
- POJ1005解题报告
- Codeforces Round #407 (Div. 2)解题报告
- BestCoder16 1002.Revenge of LIS II(hdu 5087) 解题报告
- POJ1118解题报告
- 训练题 连接格点(并查集运用) 解题报告
- 【LeetCode】Keyboard Row 解题报告
- POJ 1003(Hangover 简单数学) 解题报告
- 学姐吃牛排[Vijos1987]解题报告
- poj 2152解题报告
- openjudge3344 冷血格斗场 解题报告
- POJ 1008(映射) 解题报告
- 哈理工oj 1353-LCM与数对解题报告
- poj 3080 Blue Jeans 解题报告
- CUGBACM Codeforces Tranning 2 解题报告