我有一个n
个正数数组。我需要将其拆分为N
个连续的子数组; n > N
。
我需要最小化[max S(j) over j] - [min S(j) over j]
,
其中S(j)
表示j-th
子数组(j = 1,...,N)
中元素的总和。
即,所有子数组的元素总数应“相同”。
我确定这个问题是已知的。有人可以指出我算法,实现或出版物吗?
答案 0 :(得分:1)
此问题等效于找到max S(j) over all j
的最小值。
直觉:
假定所有可能的max S(j) over all j
中的最小值为xmax
,因此结果将为xmax - xmin
。
假设另一个ymax > xmax
可以为我们提供更好的结果,这意味着ymax - ymin
<xmax - xmin
-> ymin > xmin
-> min S(j) - ymax
> min S(j) - xmax
,这应该不会发生。
因此,问题指向找到max S(j) over all j
的最小值
这可以通过使用二进制搜索来解决。
假设整个数组的总和为X
,那么我们有算法:
int start = 0;
int end = X;
int result = 0;
while(start <= end){
int mid = (start + end)/2;
for(int i = 0; i < n; i++){
if sum of current segment > mid
split
}
if total segment > N
start = mid + 1;
else
update result;
end = mid - 1;
}
答案 1 :(得分:0)
找到整个数组的总和并调用T
,然后执行k = T / N
以确定第一个子数组元素的理想总和。然后线性创建第一个子数组(从数组的开头开始),同时在确定子数组是否应该/不应该包含下一个子数组时,尝试最小化k
和sum of all values in the sub-array so far + potential next element
之间的差异元素。
然后使用递归将数组的其余部分拆分为N-1
个片段,并在N == 1
(数组的其余部分是最后一个子数组)时停止。
注:并非在所有情况下都提供最佳解决方案,但是它相对较快,并且出于(动态)负载平衡的目的,存在这样的风险,即负载会经常变化,以至于任何更昂贵的(总是找到最优解)是没有意义的。