放鸡蛋问题:相同元素分配到相同的空间

标签: C语言 放鸡蛋 相同元素 相同空间

by 小威威


1.引入

放鸡蛋问题就是指将相同元素分配到相同空间这一类问题。具体问题就是:现在有n个相同的鸡蛋,m个相同的篮子,将这n个鸡蛋分配到篮子中,且篮子可以为空,问一共有多少种分配方法?

我们的第一反应就是排列组合,而这一问题很类似于我们高中的隔板法。然而,如果你沿着这条思路,恐怕你就会走近进胡同却又浑然不知。

因为隔板法是针对相同元素分配到不同空间而设计的,注意,是不同空间。倘若篮子是不同的,那么就可以用隔板法来解决这一问题。而如今是相同篮子。也许你会说可以将结果除以某个组合数,但我是试过了,行不通,如果你能做到,欢迎在下面评论,或者私我,不胜感激。

但是,隔板法行不通并不意味着这道题和排列组合毫无关联,因为解这道题还是需要排列组合中的分类思想。

2.问题分析

现在有n个相同的鸡蛋,m个相同的篮子,将这n个鸡蛋分配到篮子中,且篮子可以为空,问一共有多少种分配方法?

拿到这道题,我们首先要进行第一次分类,也就是篮子数与鸡蛋数的大小关系。当鸡蛋数小于篮子数时,无论怎么放,都会有空篮子,并且篮子是相同的,不妨就将这几个篮子删去,即让篮子数等于鸡蛋数。此时,就能将鸡蛋数小于篮子数这一情况归于下面一种情况。当鸡蛋数大于等于篮子数时,此时要进行第二次分类:因为篮子可以为空,所以分为没有空篮子,一个空篮子,两个空篮子….最多可以有m-1个篮子。如此分类保证了除了空篮子以外,其他篮子至少要有一个鸡蛋,这样问题就容易分析多了。我们设F(m, n)为将n个鸡蛋分配到m个篮子,篮子可以为空,设T(m, n)为将n个鸡蛋分配到m个篮子,篮子不可以为空。则F(m, n)=T(m, n)+T(m,n-1)+T(m,n-2)+….+T(m, 1)。显然,要解出这一式子要用递归的思想。但对于这个式子,我们还需要变一下形,使F与T的联系更紧密。

对于1+2+3+…+10,用递归的思想就可以变成1+54=1+2+52=1+2+3+49=…=1+2+3+….+10
那么对于F(m, n)=T(m, n)+T(m,n-1)+T(m,n-2)+….+T(m, 1),用递归的思想就可以变成:
F(m,n) = T(m,n) + F(m,n-1)
对于T(m, n),指将n个鸡蛋放到m个篮子,且每个篮子都不为空。即每个篮子至少有一个。所以我们先给每个篮子分一个鸡蛋,剩下n-m个鸡蛋可以任意分配,即以一开始可以为空篮子的规则分配(此时可以将每个篮子里的那个鸡蛋忽略)。那么T(m, n)就变成了F(m, n-m).则F(m, n) = F(m, n-m) + F(m, n-1)。如此,递归原型出现了。如今,我们要设计递归中止的条件。(注意,在递归的过程中,如果出现鸡蛋数少于篮子数,就让篮子数等于鸡蛋数,然后再进行下一步操作。)当篮子数为1时,显然只有一种情况,所以返回1;还有一种情况返回1就是当篮子数为0。如F(2,2)=F(0,2) + F(1,2)。因为当鸡蛋数为0,篮子数不为0时,篮子数会被赋值为鸡蛋数,即为0,由于判断条件,F(0,2)会被忽略,而F(0,2)的原型是T(2,2),也是属于一种情况,所以要补上。当鸡蛋数为0时,显然不能分配,即0种情况,所以返回0。如此,递归就设计完成了~

此题的关键之一就是将空篮子的个数进行分类,其二就是确定所有篮子都不是空篮子时,先给每个篮子分配一个鸡蛋,剩余的鸡蛋按照原来的规则分配。

3.实例

Erin买了不少鸡蛋,她发现一天吃不完这么多,于是决定把n个同样的鸡蛋放在m个同样的篮子里,允许有的篮子空着不放,请问共有多少种不同的放法呢?

注意:2,1,1和1,2,1 是同一种分法。

Input
第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含二个整数m和n,以空格分开。1<=m,n<=10。

Output
对输入的每组数据m和n,用一行输出相应的结果。

例如:

Input:

4

3 8

4 7

2 4

4 2

Output:

10

11

3

2

(注意结尾有换行)

代码:

# include <stdio.h>
int Calculate_ways(int egg_number, int backet);
int main(void) {int T, i, number;scanf("%d", &T);i = 0;while (i < T) {int x1, x2;scanf("%d%d", &x1, &x2);number = Calculate_ways(x2, x1);printf("%d\n", number);i++;}
}
int Calculate_ways(int egg_number, int backet) {if (egg_number < backet) backet = egg_number;if (backet == 1 || backet == 0) return 1;if (egg_number == 0) return 0;return Calculate_ways(egg_number-backet, backet)+ Calculate_ways(egg_number, backet-1);
}

以上内容皆为本人观点,欢迎大家提出批评和指导,我们一起探讨。


放鸡蛋问题:相同元素分配到相同的空间相关推荐

  1. 相同元素分配到相同空间问题(放鸡蛋问题)详解

    在高中的时候,我们接触到的排列组合问题是将相同元素放到不同空间,这个很好求. 那么相同元素分配到相同空间怎么办呢? 我在网上大概查了一下,但是也没有解释的很详细的,所以就根据已有的进行了推导,并对已有 ...

  2. 蓝桥杯java第五届决赛第三题--格子放鸡蛋

    标题:格子放鸡蛋X星球的母鸡很聪明.它们把蛋直接下在一个 N * N 的格子中,每个格子只能容纳一枚鸡蛋.它们有个习惯,要求:每行,每列,以及每个斜线上都不能有超过2个鸡蛋.如果要满足这些要求,母鸡最 ...

  3. java分配数组空间使用的关键字_创建数组时为数组元素分配内存空间的 Java 关键字是________(5.0分)_学小易找答案...

    [填空题]若已有数组说明"char s[];",则创建 20 个字符的数组的语句是s=______________; (5.0分) [单选题]下列关于数组的描述错误的是(3.0分) ...

  4. Linux分配全部可用磁盘空间流程

    Linux分配全部可用磁盘空间流程 查看所有磁盘 fdisk -l查看分区表 fdisk /dev/vda n p enter enter enter w同步分区操作 partprobe将物理硬盘分区 ...

  5. 前序遍历m-ary树_在Ruby中使用ary [index]- object进行数组元素分配

    前序遍历m-ary树 In the last article, we have learnt how we can add an object as an element to the object ...

  6. 前序遍历m-ary树_在Ruby中使用ary [start,length]- object进行数组元素分配

    前序遍历m-ary树 In the last article, we have learnt how we can add an object as an element to the object ...

  7. 使用flex布局把三个元素分配成两列,第二列垂直布局两个元素

    https://stackoverflow.com/questions/43056180/flexbox-3-divs-two-columns-one-with-two-rows/43057107 最 ...

  8. JVM学习笔记之-堆,年轻代与老年代,对象分配过程,Minor GC、Major GC、Full GC,堆内存大小与OOM,堆空间分代,内存分配策略,对象分配内存,小结堆空间,逃逸分析,常用调优工具

    堆的核心概述 概述 一个JVM实例只存在一个堆内存,堆也是Java内存管理的核心区域.Java堆区在JVM 启动的时候即被创建,其空间大小也就确定了.是JVM管理的最大一块内存空间. 堆内存的大小是可 ...

  9. Linux的默认给home分配多少,Linux 分配/home的磁盘空间给根目录

    Linux版本: Linux 6.9 系统安装完成以后,根目录的磁盘空间只有50G,剩余的大部分空间会分配到/home目录下面.使用过程中很少使用到/home目录,所以我们来把/home目录的磁盘空间 ...

  10. c语言分配多一个字符空间,关于C语言动态给字符串分配内存空间问题

    在动态分配的空间中如何输入字符串,关于C语言动态给字符串分配内存空间的问题相信很多朋友都不太了解,下面维维带来相关解答,赶紧看看吧. 用malloc来分配内存空间. 即输入几个字节的字符 系统就自动帮 ...

最新文章

  1. 基于社交媒体的政治情感分析的相关论文
  2. 使用DDMS抓取安卓APP的奔溃日志
  3. Python之初识函数(Day11)
  4. Java中的移位操作以及基本数据类型转换成字节数组【收集】
  5. 深入理解Java内存模型--转载
  6. 腾讯云搭建WordPress个人博客小白版流程分享
  7. centos 安装 telnet
  8. JavaScript实现数除以二divideByTwo算法(附完整源码)
  9. Andorid ListView使用技巧
  10. Gradle实战:发布aar包到maven仓库
  11. C语言入门经验:零基础如何学习C语言?
  12. 创建数组表格PHP苹果价格,如何从PHP数组创建HTML表?
  13. 【JZOJ4920】【NOIP2017提高组模拟12.10】降雷皇
  14. 计算机网络同传步骤,HP网络同传使用方法Word版
  15. 计算机组成原理考试试题答案,计算机组成原理期末考试试题及答案 (精选可编辑)...
  16. 扩展GridView控件(3) - 根据按钮的CommandName设置其客户端属性
  17. steam怎么设公用计算机,steam怎样设置家庭共享 steam家庭共享设置办法
  18. 传智播客黑马java 30期_黑马传智播客JavaEE57期 2019最新基础+就业+在职加薪_汇总...
  19. cad打印去掉边框_CAD打印的时候如何去掉打印线框?
  20. java学习,入门篇-HelloWorld

热门文章

  1. 2021阿里云双11云服务器配置表汇总!
  2. Wex5打包报错的解决办法
  3. citespace下载安装教程
  4. [工具分享]阿里云语音合成方言和外语Windows版本
  5. L2-016 愿天下有情人都是失散多年的兄妹 (25 分) (DFS)
  6. python爬虫之xpath解析(附实战)
  7. 多台服务器集群部署方案
  8. DOTA 104个英雄416个技能、104首情诗
  9. 4n35光耦引脚图_常见的高速光耦引脚图
  10. 平板无线网无法连接网络连接服务器,平板电脑可以连接无线网络但上不了网的解决方法...