410. Split Array Largest Sum
https://leetcode.com/problems/split-array-largest-sum/
对由非负数组成的数组划分成给定的m份,最小化和最大的子数组。解这种给定背包数,找能把物品(质量值为正数)一一全部放进去的背包最小容量的题用二分最快。对每个二分mid时检查mid是否能让数组在m次分完,当需要的次数大于D时说明mid取小了,start + 1。
/*
* @lc app=leetcode id=410 lang=cpp
*
* [410] Split Array Largest Sum
*/
class Solution {
public:
int splitArray(vector<int>& nums, int m) {
const auto check = [](vector<int>& weights, long mid) {
long sum = 0, c = 1;
for (int w : weights) {
if (sum + w > mid) {
sum = 0;
++c;
}
sum += w;
}
return c;
};
long start = 1, end = 1;
for (int w : nums) {
start = max(start, (long) w);
end += w;
}
while (start < end) {
long mid = start + (end - start) / 2;
if (m < check(nums, mid)) {
start = mid + 1;
} else {
end = mid;
}
}
return start;
}
};
partition + optimal用DP。action为对让当前num[j]分别和不同的前面的元素k组成一个划分[k+1, j],受限于前面的划分数目。因此把划分数encoding进状态,题目所求encoding进值,dp[i][j]表示从0到j形成i个划分的最优解,前面[0, k]有i - 1个划分,即dp[i - 1][k]。三重循环。
代码参考了花花的。
Last updated
Was this helpful?