LeetCode/公平分发饼干
给你一个整数数组 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(); //返回全部枚举完的分配结果
}
};