JAVA程序设计:得到新鲜甜甜圈的最多组数(LeetCode:1815)

有一个甜甜圈商店,每批次都烤 batchSize 个甜甜圈。这个店铺有个规则,就是在烤一批新的甜甜圈时,之前 所有 甜甜圈都必须已经全部销售完毕。给你一个整数 batchSize 和一个整数数组 groups ,数组中的每个整数都代表一批前来购买甜甜圈的顾客,其中 groups[i] 表示这一批顾客的人数。每一位顾客都恰好只要一个甜甜圈。

当有一批顾客来到商店时,他们所有人都必须在下一批顾客来之前购买完甜甜圈。如果一批顾客中第一位顾客得到的甜甜圈不是上一组剩下的,那么这一组人都会很开心。

你可以随意安排每批顾客到来的顺序。请你返回在此前提下,最多 有多少组人会感到开心。

 

示例 1:

输入:batchSize = 3, groups = [1,2,3,4,5,6]
输出:4
解释:你可以将这些批次的顾客顺序安排为 [6,2,4,5,1,3] 。那么第 1,2,4,6 组都会感到开心。
示例 2:

输入:batchSize = 4, groups = [1,3,2,5,2,2,1,6]
输出:4
 

提示:

1 <= batchSize <= 9
1 <= groups.length <= 30
1 <= groups[i] <= 109

思路:比赛中曾想过用状压,但是没有想到优化复杂度的解法,于是不了了之,在题解中发现了一个优美并且容易理解的31进制枚举状态的算法,真的学到了!

class Solution {

    private int batchSize;
    private Map<Long, Integer> map;

    public int maxHappyGroups(int batchSize, int[] groups) {
        this.batchSize = batchSize;
        map = new HashMap<>();
        long state = 0;
        int m = 0;
        for (int element : groups) {
            element %= batchSize;
            if (element == 0) m++;
            else state += 1L << (element * 5);
        }
        return m + dfs(0, state);
    }

    private int dfs(int cur, long state) {
        if (map.containsKey(state))
            return map.get(state);
        if (state == 0)
            return 0;
        int res = 0;
        for (int i = 1; i < batchSize; i++) {
            if ((state >> (i * 5)) % 32 > 0) {
                int now = dfs((cur + i) % batchSize, state - (1L << (i * 5)));
                res = Math.max(res, cur == 0 ? now + 1 : now);
            }
        }
        map.put(state, res);
        return map.get(state);
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值