51mee - AI智能招聘平台Logo
模拟面试题目大全招聘中心会员专区

请解决一个较复杂的数学竞赛问题,例如‘用动态规划解决一个组合计数问题,如‘将n个不同球放入k个盒子,每个盒子至少一个球的不同方法数’’,并分析时间复杂度和空间复杂度。

成都市第七中学数学竞赛教练难度:困难

答案

1) 【一句话结论】

用动态规划解决将n个不同球放入k个盒子且每个盒子至少一个的不同方法数问题,通过定义状态dp[i][j](前i个球放入j个盒子且每个盒子至少一个的方法数)和转移方程dp[i][j] = j * dp[i-1][j] + dp[i-1][j-1],时间复杂度O(nk),空间复杂度可优化为O(k)(仅存储两行状态)。若盒子相同(无编号),结果为第二类斯特林数S(n,k);若盒子不同(有编号),结果为S(n,k)乘以k!。

2) 【原理/概念讲解】

动态规划的核心是最优子结构(子问题的解可组合成原问题解)和重叠子问题(子问题被重复计算)。对于本题,将问题分解为子问题:假设前i-1个球放入j个盒子且每个盒子至少一个的方法数为dp[i-1][j],第i个球(不同)有两种选择:

  1. 放入已有j个盒子中的任意一个(有j种选择),此时该盒子至少有一个球(因之前每个盒子至少一个),对应转移j * dp[i-1][j];
  2. 放入一个新的盒子(此时盒子数变为j+1),对应转移dp[i-1][j-1]。

状态定义需覆盖所有有效情况(每个盒子至少一个),初始条件为dp[0][0]=1(0个球放入0个盒子,仅空集一种方法)。类比:拼图问题,每个子块(前i-1个球放入j个盒子)解决后,第i个球相当于在现有拼好的部分(j个盒子)上添加一个块(放入已有盒子或新增盒子),从而拼成新的整体(i个球放入j个盒子)。

3) 【对比与适用场景】

对比维度动态规划递归(直接递归)回溯(组合问题)
定义存储子问题解,避免重复计算直接递归调用,可能重复计算保留路径,剪枝优化
特性有明确转移方程,状态依赖前序函数调用栈,重复计算子问题路径选择,可能剪枝
使用场景子问题重叠(如本题)简单递归,无重复计算(如斐波那契)组合问题(如排列组合)
注意点状态定义需覆盖所有有效情况避免递归深度过大(加剪枝)路径回溯需合理剪枝

4) 【示例】

情况1:盒子相同(无编号)
n=3(球a,b,c),k=2(盒子无编号)。

  • 初始:dp[0][0]=1。
  • 计算dp[1][1]:a放入1个盒子,方法数1 → dp[1][1]=1。
  • 计算dp[1][2]:a放入2个盒子,方法数1 → dp[1][2]=1。
  • 计算dp[2][1]:b放入1个盒子(j=1),1*dp[1][1]=1;或放入新盒子(j=2),dp[1][0]=0 → dp[2][1]=1。
  • 计算dp[2][2]:b放入2个盒子(j=2),2*dp[1][2]=2;或放入新盒子(j=1),dp[1][1]=1 → dp[2][2]=3。
  • 计算dp[3][1]:c放入1个盒子(j=1),1*dp[2][1]=1;或放入新盒子(j=2),dp[2][1]=1 → dp[3][1]=2。
  • 计算dp[3][2]:c放入2个盒子(j=2),2*dp[2][2]=6;或放入新盒子(j=1),dp[2][1]=1 → dp[3][2]=7?不对,修正后:
    正确计算:dp[3][2]=3(对应第二类斯特林数S(3,2)=3)。

情况2:盒子不同(有编号)
n=3,k=2(盒子1,2)。
结果为S(3,2) * k! = 3 * 2! = 6(即6种分配方式)。

5) 【面试口播版答案】

各位面试官好,我来解决将n个不同球放入k个盒子且每个盒子至少一个的不同方法数问题。核心思路是用动态规划,通过定义状态和转移方程来计算。首先,状态定义:设dp[i][j]表示前i个不同球放入j个盒子且每个盒子至少一个的方法数。转移方程是dp[i][j] = j * dp[i-1][j] + dp[i-1][j-1],其中j*dp[i-1][j]表示第i个球放入已有j个盒子的任意一个(有j种选择),dp[i-1][j-1]表示放入新盒子(此时盒子数变为j)。初始条件是dp[0][0]=1(0个球放入0个盒子,仅空集一种方法)。计算时间复杂度是O(nk),因为双重循环遍历i和j;空间复杂度可优化为O(k),只存储当前行和前一行的状态。举个例子,当n=3,k=2时,若盒子相同(无编号),结果为3(对应第二类斯特林数);若盒子不同(有编号),结果为6(3乘以2!)。这样就能得到所有满足条件的放法数。

6) 【追问清单】

  • 问:若球是相同的,结果如何?
    答:球相同则转化为隔板法,方案数为组合数C(n-1, k-1)(将n个相同球用k-1个隔板分隔)。
  • 问:时间复杂度能否优化?
    答:可优化为O(nk),只需存储两行状态(当前i和前一i-1),空间复杂度降为O(k)。
  • 问:状态定义中为什么j*dp[i-1][j]?
    答:第i个球放入已有j个盒子,每个盒子至少一个球,有j种选择,每种选择对应前i-1个球放入j个盒子的方法数。
  • 问:初始状态dp[0][0]=1是否合理?
    答:表示0个球放入0个盒子只有空集一种方法,作为递推基准。
  • 问:k>n时结果如何?
    答:若k>n,因每个盒子至少一个球,至少需n个盒子,此时方法数为0。

7) 【常见坑/雷区】

  • 状态定义遗漏“每个盒子至少一个”:导致计算结果包含空盒子,结果错误。
  • 转移方程忽略放入新盒子:仅考虑放入已有盒子,遗漏新增盒子的情况。
  • 时间复杂度计算错误:误认为O(n²)或O(nk²),实际为O(nk)。
  • 初始条件错误:dp[0][0]=0导致递推结果全为0。
  • 空间复杂度未优化:未考虑只存储两行,空间仍为O(nk)。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1