火龙信奥
  • 首页
  • 课程
  • 题库
  • 打卡
    • 代码对战
    • 快速对战
  • 题单
  • 团队
  • 荣誉墙
  • 商城
  • 登录 / 注册

放球问题 (Twelvefold Way)

作者: 作者的头像   huolong , 时间:2026-08-06 13:19:10 , 所有人可见, 阅读  5

算法讲义:放球问题 (Twelvefold Way) 汇总

在组合数学中,将 $n$ 个球放入 $m$ 个盒子的问题,根据球是否相同、盒子是否相同、是否允许空盒,可以划分为 8 种基本情况。


核心模型分类表

球 盒子 空盒 数学模型 公式
不同 不同 允许 基础幂运算 $m^n$
不同 不同 不允 第二类斯特林数 × 排列 $m! \cdot S_2(n, m)$
不同 相同 允许 斯特林数之和 $\sum_{i=1}^m S_2(n, i)$
不同 相同 不允 第二类斯特林数 $S_2(n, m)$
相同 不同 允许 隔板法(扩展) $\binom{n+m-1}{m-1}$
相同 不同 不允 隔板法 $\binom{n-1}{m-1}$
相同 相同 允许 整数拆分 $f(n, m) = f(n-m, m) + f(n, m-1)$
相同 相同 不允 整数拆分(偏置) $f(n-m, m)$

1. 球不同,盒不同

1.1 允许为空 (Case 6.3)

每个球都有 $m$ 种独立的选择。 - 公式:$m^n$

1.2 不允许为空 (Case 6.5)

先将 $n$ 个不同球分成 $m$ 个非空集合(相同盒子),由于盒子不同,需要全排列。 - 公式:$m! \cdot S_2(n, m)$


2. 球不同,盒相同

2.1 不允许为空 (Case 6.4)

即第二类斯特林数 $S_2(n, m)$。表示将 $n$ 个不同元素划分为 $m$ 个非空子集的方案数。 - 递推公式:$S_2(n, m) = S_2(n-1, m-1) + m \cdot S_2(n-1, m)$ - 含义:新球要么新开一个盒子,要么放入已有的 $m$ 个盒子的其中一个。

2.2 允许为空 (Case 6.6)

枚举最终使用了多少个盒子。 - 公式:$\sum_{i=1}^m S_2(n, i)$ - 注:当 $m=n$ 时,结果为贝尔数 $B_n$。


3. 球相同,盒不同(隔板法)

3.1 不允许为空 (Case 6.7)

在 $n$ 个球产生的 $n-1$ 个间隙中插入 $m-1$ 个隔板。 - 公式:$\binom{n-1}{m-1}$

3.2 允许为空 (Case 6.8)

方法一(虚物法):借 $m$ 个球过来,每个盒子分一个,最后再拿走。等价于 $n+m$ 个球不允许为空放进 $m$ 个盒子。 方法二(多项式):等价于 $x_1 + x_2 + \dots + x_m = n$ 的非负整数解。 - 公式:$\binom{n+m-1}{m-1}$


4. 球相同,盒相同(整数拆分)

4.1 允许为空 (Case 6.1)

等价于将整数 $n$ 拆分为不超过 $m$ 个整数的和。 - 状态定义:$f(n, m)$ 为方案数。 - 转移方程:$f(n, m) = f(n-m, m) + f(n, m-1)$ - $f(n, m-1)$:至少有一个盒子为空。 - $f(n-m, m)$:每个盒子都至少放了一个球,先把 $m$ 个盒子铺满。

4.2 不允许为空 (Case 6.2)

先把 $m$ 个盒子各放一个球,剩下的 $n-m$ 个球随意放。 - 公式:$f(n-m, m)$


5. 代码实现技巧(C++)

第二类斯特林数 (Stirling Number 2)

long long S2[101][101];
void init_stirling(int n, int m) {
    for (int i = 0; i <= n; i++) S2[i][i] = 1;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j < i; j++) {
            S2[i][j] = (S2[i-1][j-1] + j * S2[i-1][j]);
        }
    }
}

整数拆分 (Integer Partition)

long long dp[101][101];
void init_partition(int n, int m) {
    for (int i = 0; i <= m; i++) dp[0][i] = 1;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (i >= j) dp[i][j] = dp[i-j][j] + dp[i][j-1];
            else dp[i][j] = dp[i][j-1];
        }
    }
}

总结口诀

  1. 球异盒异:看幂次。
  2. 球异盒同:斯特林。
  3. 球同盒异:隔板法。
  4. 球同盒同:数拆分。
  5. 空盒不空:先占位。

—— 本文来自火龙信奥(义乌睿码科技):义乌青少年信息学奥赛与编程教育平台,专注 CSP-J/S、NOIP、GESP 竞赛培训,线上线下融合教学,助力编程升学。网址:hlcoding.com

©2026加盟我们 | 关于我们 | ACM课程 | 常见问题 | 成果墙 | 评测记录 | 浙ICP备2021013995号
在线画图 | OI WIki | 打字练习
火龙信奥
请输入登录信息


请完成安全验证
验证码底图 滑块
向右拖动滑块完成验证
请输入用户名 / 绑定的手机号码



请输入注册信息(手机号验证码注册)





验证码5分钟有效,60秒内不可重复获取,每日最多3次

微信登录

微信登录二维码

正在生成二维码...

账号已过期,请续期。
去续期

绑定手机号

📱

为了更好地保护您的账号安全,享受完整的平台服务

请您尽快绑定手机号码