[dfs] 2305. 公平分发饼干

565 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情

每日刷题 2022.06.02

题目

  • 给你一个整数数组 cookies ,其中 cookies[i] 表示在第 i 个零食包中的饼干数量。另给你一个整数 k 表示等待分发零食包的孩子数量,所有 零食包都需要分发。在同一个零食包中的所有饼干都必须分发给同一个孩子,不能分开。
  • 分发的 不公平程度 定义为单个孩子在分发过程中能够获得饼干的最大总数。
  • 返回所有分发的最小不公平程度。

示例

  • 示例1
输入:cookies = [8,15,10,20,8], k = 2
输出:31
解释:一种最优方案是 [8,15,8][10,20] 。
- 第 1 个孩子分到 [8,15,8] ,总计 8 + 15 + 8 = 31 块饼干。
- 第 2 个孩子分到 [10,20] ,总计 10 + 20 = 30 块饼干。
分发的不公平程度为 max(31,30) = 31 。
可以证明不存在不公平程度小于 31 的分发方案。
  • 示例2
输入:cookies = [6,1,3,2,2,4,1,2], k = 3
输出:7
解释:一种最优方案是 [6,1][3,2,2][4,1,2] 。
- 第 1 个孩子分到 [6,1] ,总计 6 + 1 = 7 块饼干。 
- 第 2 个孩子分到 [3,2,2] ,总计 3 + 2 + 2 = 7 块饼干。
- 第 3 个孩子分到 [4,1,2] ,总计 4 + 1 + 2 = 7 块饼干。
分发的不公平程度为 max(7,7,7) = 7 。
可以证明不存在不公平程度小于 7 的分发方案。

提示

  • 2 <= cookies.length <= 8
  • 1 <= cookies[i] <= 105
  • 2 <= k <= cookies.length

解题思路

  • 一开始这道题完全没有思路,查看别人的解法用回溯,可是还是不知道怎么求解,一般回溯题目我都是要画出一个决策树来整理思路。
  • 回顾一下之前的题目:[1723. 完成所有工作的最短时间] 题目中要求:让我们尽可能使得工人中的最大工作时间最小
  • 分析回溯的几个关键点:
    1. 结束条件:也就是工人任务已经都分配下去,没有再可分配的了,我们要更新结果值即先取出工人中的最大工作时间,然后更新;
    2. 做出选择:也就是每次可分配的工人,那么k个工人就有k个选择,所以遍历这k个工人。做选择前我们还要进行减枝,如果分给这个工人后,超过目前的res,这个分配方案肯定不行,所以要剪掉;
    3. 撤销选择:也就是每次结束后,向上回溯,把刚才给前一个工人的任务撤销,分给下一个工人
  • 注意⚠️:当撤销选择后,这个工人的任务一个也没有了,那就不用再继续给下一个工人了,这样会出现重复的工作,任务分给谁没有先后顺序的,我们想得到的是一种尽可能公平的分配,比如[1](#)和[](#)是一样的分配效果。

AC代码

/**
 * @param {number[]} cookies
 * @param {number} k
 * @return {number}
 */
var distributeCookies = function(cookies, k) {
  // 暴力求解
  let ren = new Array(k).fill(0), c = cookies, n = c.length,ans = Infinity;
  function dfs(idx) {
    if(idx == n){
      // 需要比较求出最大值
      ans = Math.min(ans, Math.max(...ren));
      return;
    }
    for(let i = 0; i < k; i++) {
      ren[i] += c[idx];
      dfs(idx + 1);
      ren[i] -= c[idx];
    }
  }
  dfs(0);
  return ans;
};