LeetCode/公平分发饼干

发布时间 2023-07-05 02:29:36作者: 失控D大白兔

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

1. 状态压缩 + 动态规划

dp[mask][i]表示在mask状态下,划分i次的最小不公平程度
dp[mask][i]可以由子集的上一个状态转移得到

class Solution {
public:
    int distributeCookies(vector<int> &cookies, int k) {
        int n = cookies.size();
        vector<int> sum(1 << n); //预先计算各种组合下的和
        for (int i = 0; i < n; i++)
            for (int j = 0, bit = 1 << i; j < bit; j++) //根据小的进行转移,减少枚举判断
                sum[bit | j] = sum[j] + cookies[i];

        vector<int> f(sum); //f[i]记录i状态下的不公平程度,初始状态未进行划分,为对应元素和
        //注意这里是二维动态规划,压缩成一维
        for (int i = 1; i < k; i++) { //划分k-1次
            for (int j = (1 << n) - 1; j; j--) { //状态由大到小
                for (int s = j; s; s = (s - 1) & j) { //遍历该状态下所有子集,进行一分为二
                    f[j] = min(f[j], max(f[j ^ s], sum[s])); //一分为二的最小不公平程度
                }
            }
        }
        return f.back(); //返回全部枚举完的分配结果
    }
};