[LeetCode]5289. 公平分发饼干

75 篇文章 0 订阅

题目


5289. 公平分发饼干
给你一个整数数组 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

方法1:回溯

        int n;//cookies的大小
        int totalMax = Integer.MAX_VALUE;
        int k;//孩子的数量

        public int distributeCookies(int[] cookies, int k) {
            n = cookies.length;
            this.k = k;
            //让大的饼干在前面
            cookies = IntStream.of(cookies)          // 变为 IntStream
                    .boxed()           // 装盒变为 Stream<Integer>
                    .sorted(Comparator.reverseOrder()) // 按自然序相反排序
                    .mapToInt(Integer::intValue)       // 变为 IntStream
                    .toArray();        // 又变回 int[]
            int[] arr = new int[k];
            backtrace(0, arr, cookies);
            return totalMax;

        }


        /**
         * @param index   当前处理到的cookies数据的下标
         * @param arr     当前k个小孩,每人一个袋子,每个袋子里的饼干的总数
         * @param cookies 饼干的数组
         */
        private void backtrace(int index, int[] arr, int[] cookies) {
            if (index == n) {//处理的下标来到cookies数组的最后,说明这时候所有的饼干都分完了
                int maxx = 0;//记录当前这种分法下的最大饼干
                for (int x : arr) maxx = Math.max(maxx, x);
                totalMax = Math.min(totalMax, maxx);//全局的最小饼干数量
                return;
            }
            //统计当前的小孩还没有分到饼干的数量
            int empty = 0;
            for (int x : arr) {
                if (x == 0) empty++;
            }
            //剩余的可供分配的饼干的数量是 n-index个,但是要分饼干的小孩有empty个,不能保证剩下的小孩每人都分到饼干
            if (empty > n - index) return;
            for (int i = 0; i < k; i++) {
                //规定index为0的饼干即第一块饼干分配给第一个小孩
                if (i > 0 && index == 0) {
                    return;
                }
                //当前小孩的数量和上一个小孩的数量相等(饼干数量),此种结果重复了
                if (i > 0 && arr[i] == arr[i - 1]) continue;
                //当前小孩拿的饼干,比之前获取到的全局最小值还要大,说明当前的这种方案下,肯定不如totalMax的方案下的分配方式
                if (arr[i] + cookies[index] > totalMax) continue;
                arr[i] += cookies[index];
                backtrace(index + 1, arr, cookies);
                arr[i] -= cookies[index];
            }
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值