SWE · VO Coding

Airbnb Menu Coding:单品与套餐覆盖最多三种需求的最低价

菜单项可含一种或多种食物;最多三类 wanted food 时用位掩码枚举组合,并说明重复购买与多余食物口径。

题目重点:菜单项可含一种或多种食物;最多三类 wanted food 时用位掩码枚举组合,并说明重复购买与多余食物口径。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 训练版每个菜单项最多选一次,菜单项可带多种食物,价格非负;如果允许无限重复买且只问覆盖,非负价格使重复同一项不改覆盖也不更优。
  • 买到不在 wanted 内的食物允许,但不贡献覆盖;如果严格不允许额外食物,需筛掉这些菜单项。
  • 输出一组达到最低价的菜单项 ID;同价训练版按原输入索引序列词典序取最小。

解题路线

  1. 给 wanted 的每个不同食物分配 0..k−1 位,k≤3;每个菜单项的食物集合映射成覆盖 mask,重复食物只算一位。
  2. 0-1 DP:dp[mask] 保存当前已处理菜单项下覆盖该 mask 的最小成本和所选索引;初始 dp[0]=0。处理一项时用旧 dp 快照转移到 mask|itemMask,避免本轮重复选同一项。
  3. 最终读 dp[(1<<k)−1];若不存在则返回无解。追踪父指针或保存组合用于恢复所选菜单项,同价按定义比较。
  4. 最多三种需求时仅 8 个状态,可直接枚举;如果菜单项有负价或购买数量限制变化,规则要重算。

手动走一遍

训练例 wanted={wings,fries}。菜单 burger 50 覆盖 0 位,fries 30 覆盖 fries 位,burger+wings 70 覆盖 wings 位;选 fries 和 burger+wings 成本 100。Burger 单品不能替代 wings,买到额外 burger 在本训练版允许。

规模与取舍

M 个菜单项、k≤3,DP 时间 O(M·2^k),存成本 O(2^k);若为每个状态保存完整组合,复制成本与组合长度相关,记录前驱可压低。

易错点与追问

容易失分的边界

  • 按菜单项名称字符串子串匹配而非食物集合。
  • 0-1 转移原地向前更新,意外重复选同一项。
  • 忽略多余食物是否允许。
  • 同价组合未定义输出顺序。
  • 把价格 50/30/70 误读为每种食物单独价格。

继续深挖

  • 如果需要每种食物至少两份如何扩状态?
  • 无限购买且有优惠/负价怎么办?
  • 菜单数量极大而 k=3 怎么去除支配项?
  • 是否允许额外食物会怎样改变结果?
✓已复制微信号!