排列组合问题:n个相同的球,放入m个不同的盒子,每个盒子至少k个球,求总放法。

如题所示,这是我2023年9月份,参与华为OD面试的时候,进入第三轮面试,面试官为了考算法,给了这道题,当时我没做出来,最近研究了一下这个题目。

这个题目其实就是普通的排列组合,做了一个变种:把n-mk个球放入m个盒子,盒子容许为空,求总放法。

一般而言,如果n个球,放入m个盒子,如果盒子不为空那么结果就是:

这个结果的思路就是有n个球,那么排成一排,它们之间有n-1个空隙,放入m个盒子,就是分成m份,那么就需要在n-1个空隙中插入m-1个隔板。所以,这个方法也叫隔板法或者挡板法。

比如,我们要把3个球,分成2份,不容许空。最直观的做法,就是:

以上的结果用公式表示:

改变一下条件,如果容许分到的结果为空,那么结果就是:

思路和上面类似,只不过增加了为空的情况:

套用公式:

结合本题,该题多了一个条件,就是每个盒子放k个球,那么剩下n-mk个球,放入m个盒子,每个盒子可以为空,结合以上的结论公式就是:

有了公式,算法就简单了,排列组合结果计算,需要使用到阶乘。

如下是通过java实现的算法示例:

java 复制代码
/*
 *    xxx co.ltd Copyright @ 2023-2023 All Rights Reserved
 */

package com.xxx.hw;

import java.util.Scanner;

/**
 * 描述信息
 *
 * @author Administrator
 * @since 2023/9/27 14:58
 * 题目描述
 * 一个排列组合问题:有m个盒子(盒子与盒子之间是不同的),n个球(球与球之间是完全相同的),要求每个盒子里至少放k个球,共有多少种不同的方法?
 * <p>
 * 解答要求
 * 时间限制:1000ms, 内存限制:100MB
 * 输入
 * 每组测试用例占一行,包含三个整数m,n,k(1<=m<=100,1<=n<=1000,0<=k<=20)
 * <p>
 * 输出
 * 共有多少种不同的方法,由于结果可能超出整数int范围,输出对5201314取余后的值。
 * <p>
 * 样例
 * 输入样例 1
 * <p>
 * 2 3 1
 * 输出样例 1
 * <p>
 * 2
 */
public class Test {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            int boxNum = scanner.nextInt();
            int ballNum = scanner.nextInt();
            int kNum = scanner.nextInt();
            System.out.println(permutation(boxNum, ballNum, kNum));
        }
        scanner.close();
    }
    public static int permutation(int boxNum, int ballNum, int k) {
        int remain = ballNum - k * boxNum;
        if (remain == 0) {
            return 1;
        }
        return getResult(boxNum, remain);
    }
    public static int fun(int n) {
        if (n < 2)
            return n;
        return n * fun(n - 1);
    }
    public static int getResult(int m, int n) {
        return fun(n+m-1)/(fun(m-1)*fun(n));
    }
}

运行结果验证:

这个结果第一个示例是把3个球放入2个盒子,每个盒子至少1个球,最简单的就是:1+2=3,2+1=3两种放法。

第二个示例是把10个球,放入3个盒子,每个盒子至少2个球,综合分析10-3*2=4,剩下4个球,放入3个盒子,容许空盒,按照公式:

另外,附上一个推导公式:

这里面,盒子不为空的情况,我们很容易理解,就是,但是容许为空,这个公式是通过如下公式推导过来的:

相关推荐
_OP_CHEN2 个月前
【算法基础篇】(五十一)组合数学入门:核心概念 + 4 种求组合数方法,带你快速熟悉组合问题!
c++·算法·蓝桥杯·排列组合·组合数学·组合数·acm/icpc
普兰店拉马努金3 个月前
【高中数学/排列组合】由字母AB构成的一个6位的序列,含有连续子序列ABA的序列有多少个?
java·排列组合
nju_spy6 个月前
力扣每日一题(二)任务安排问题 + 区间变换问题 + 排列组合数学推式子
算法·leetcode·二分查找·贪心·排列组合·容斥原理·最大堆
窗户1 年前
有限Abel群的结构(1)
数学·抽象代数·排列组合
Tisfy1 年前
LeetCode 2266.统计打字方案数:排列组合
数学·算法·leetcode·动态规划·题解·排列组合
窗户1 年前
排列和组合的实现
排列组合·函数式·haskell·scheme
Espresso Macchiato2 年前
Leetcode 3234. Count the Number of Substrings With Dominant Ones
排列组合·leetcode medium·容斥原理·leetcode 3234·leetcode周赛408
AI棒棒牛2 年前
YOLOv10全网最新创新点改进系列:一文学会排列组合(“炼丹神器”)!手把手教学,保姆级教程!!!
sci·排列组合·创新·yolo模型创新·模型改进·炼丹·模块缝合
薛定谔_512 年前
Excel·VBA数组分组问题
算法·excel·vba·排列组合·分组