我有一个int
数组,其中包含{47, 94, 79, 90, 89, 14, 82, 92}
等数字。必须将数组分成三个子数组,以便每个数组的总和尽可能小,即最小。我认为它值得用递归来解决,但是这个方法让我感到厌烦,我还想到在初始数组上使用qsort
然后将它除去"贪婪"但它始终不起作用(例如取最低和最高数字等)。
例如,上面的数字将分为:
1) {94, 90, 14}
2) {92, 89}
3) {82, 79, 47}
这里第三个数组包含最高的最小和,即208
。数字的顺序无关紧要。问题是如何将数字公平地分成三组,以便它们形成最低的总和。我是否必须测试所有可能性?
答案 0 :(得分:0)
可以使用动态编程对所描述的问题进行建模。我们可以按如下方式定义状态空间。
v[i,t1,t2] := minimal load in partition 3 attainable for items
in {0,...,i} where the total load in partition 1
is exactly t1 and the total load in t2 is exactly t2
if such a load exists and positive infinity otherwise
对于州空间,i
位于{0,...n}
,t1
,t2
位于{0,...,P}
,其中P
是总和项目的上限,是客观价值的上限,以n*smax
为界,其中smax
是输入中出现的最大值。
我们获得了以下递归关系,其中案例基本上依赖于迭代选择分配给它的分区的每个元素,其中s_i
表示i
项的大小。
v[i,t1,t2] = min { v[i-1,t1-s_i,t2],
v[i-1,t1,t2-s_i],
v[i-1,t1,t2] + s_i }
最小表达式中的第一项对应于将项i
分配到分区3中,第二种情况对应于将项i
分配到分区2中,第三种情况对应于分配项{{1}填充状态空间后,可以通过评估以下表达式获得所需的结果(即分区的最小最大负载)。
i
在上面的最大表达式中,Result = min { max { t1, t2, v[n,t1,t2] : t1, t2 in {0,...,P} } }
将对应于分区1中的负载,t1
将对应于分区2中的负载和
状态值t2
对应于分区3中的负载。草绘算法的运行时间可以由v[n,t1,t2]
限制,O(n^3*smax)
是伪多项式运行时绑定。如果另外需要将项目最佳分配到分区中,则必须使用回溯或辅助数据结构。
请注意,为其中一个相同的分区赋予特殊作用似乎是假的,因为其负载是状态的值,而其他分区的负载用于状态空间的轴。此外,乍一看,国家的价值似乎可以轻易获得,因为它只是剩余的总负荷
sum_{j=1}^{i} s_i - ( t1 + t2 )
但情况并非如此,因为上述数量仅确定分区3中的负载(如果实际存在这样的分配);在状态空间的定义中,正无穷大的使用表明这种分配不存在。
该方法非常类似于here,第12页ff所描述的方法。总之,所描述的问题可以被视为调度问题,即最小化3个相同并行机器的完工时间。在所谓的three-field notation中,问题表示为P3||Cmax
,这意味着机器的数量不是输入的一部分,而是固定的。