母问题描述
n个小球放置到k个盒子求放法。不同的条件约束有不同的思考方向,这里做一下汇总。
记答案为f(n,k)
子问题一描述
以集合的划分为例信息学奥赛一本通
问题等价于在母问题的基础上补充以下条件
- n个小球均不同
- k个盒子相同,且要求所有盒子均不为空
- 同一个小球只能放入一个盒子
子问题二 描述
以放苹果为例程序设计与算法(二)算法基础_中国大学MOOC(慕课)
问题等价于在母问题的基础上补充以下条件
- n个小球均相同、 k个盒子均相同
- 允许有的盒子为空
子问题三描述
以数的划分为例P1025 [NOIP2001 提高组] 数的划分 - 洛谷
问题等价于在母问题的基础上补充以下条件
- n个小球均相同、k个盒子均相同
- 不允许出现空盒子
解决问题的出发点
这样的问题,显然是不能用枚举来做的,先用递归的方法去思考,递归出口?递归表达式?
思考的时候我们应该做到全面、考虑周到。
问题一《集合的划分》
递归边界
- n<k || k==0,f(n,k)==0;
- n==k || k==1,f(n,k)==1
寻找递归表达式
我们把n>k时情况从某一个小球(记作A),开始考虑。
- 第一种情况,f(n, k)=f(n-1, k-1) A单独作为一个集合而存在,那么剩下的n-1个小球就放置在k-1个盒子中
- 第二种情况,f(n, k) = k * f(n-1, k) A与其他若干小球共属一个集合,那么剩下的n-1个小球还是放置在k个盒子中,但是由于小球是不同的,A放在k个盒子中的任意一个都会构成一个不同的解。
那么我们所求的f(n,k)就应该是这上面两种情况之和
int f(int n, int k)
{
if(n < k || k == 0) return 0;
if(n == k || k == 1) return 1;
return f(n-1, k-1) + k * f(n-1, k);
}
问题二《放苹果》
递归边界
- n==0(至于考虑n为1还是0需要根据递归表达式可能出现的结果来改变),f(n,k)==1
- k==0,f(n,k)==0
- n≤k,f(n,k)==f(n,n)(这是一种特殊的情况,其值等于整数n的拆分方案)
寻找递归表达式
题目条件中有一点比较特殊,就是“允许盒子为空”,我们从讨论是否有盒子为空出发,把总的情况分为了两种。
- 存在盒子为空,f(n, k) = f(n, k-1) 既然存在一个空盒子,那么是否丢掉它都不会改变问题答案,所以我们就可以把问题缩小规模成将n个小球放进k-1个盒子
- 不存在盒子为空,f(n, k) = f(n-k, k) 也就是说所有的盒子中都至少存在一个小球,那么把n个小球放进k个盒子的问题就等价变成了n-k个小球放进k个盒子,也就是说把每个盒子的小球都丢掉一个
那么我们所求的f(n,k)就应该是这上面两种情况之和
int f(int n, int k)
{
if (n == 0)return 1;
if (k == 0) return 0;
if (n < k)return f(M, M);
return f(n, k - 1) + f(n - k, k);
}
这里就可以解释为什么我们考虑边界的时候是n==0而不是n==1,因为表达式中f(n - k, k)可能会导致f(0,k)的情况出现,我们需要就需要对此设定一个返回值。
问题三《数的划分》
递归边界
- k==1 || n==k,f(n,k)==1
- n<k,f(n,k)==0
寻找递归表达式
这个问题其实和上面一个问题的思考方向相同
- 至少有一个盒子只有一个小球的情况数,f(n, k) = f(n, k-1) 那么把这一个盒子和一个小球丢掉,整体答案也不会改变。
- 没有一个盒子只有一个小球的情况数,f(n, k) = f(n-k, k) 那么我们从所有的盒子中拿取一个小球出来,整体方法没有改变,同时使问题的规模减小了。
int f(int n, int k)
{
if (k == 1 || n == k) return 1;
if (n < k) return 0;
return f(n - 1, k - 1) + f(n - k, k);
}
总结
边界值的思考:可以看到,我们在思考该类问题的边界的时候,都是从极端情况,零个小球、一个小球,零个盒子、一个盒子或者是小球和盒子的数量关系使得不能构成题目的要求等入手。
递归表达式的思考:这一类问题,强调了寻找递归的时候,分类的重要性,通过合适的分类,把母问题拆分成若干个规模更小形式类似或相同的子问题。我们能够从中学习到的分类方向
- 从某一个小球入手,考虑该小球的放置情况
- 从题目一些特殊要求入手,比如可以为空,考虑有空和没空的情况
- 在解决此类“方案”的问题的时候,考虑所有的“盒子”都有的情况,扣除掉一些共同的东西,不改变答案。