【问题标题】:Minimum Complexity of two lists element summation comparison两个列表元素求和比较的最小复杂度
【发布时间】:2015-07-25 23:40:20
【问题描述】:

我有一个关于数组的算法设计问题,应该用 C 语言实现。 假设我们有一个包含 n 个元素的数组。为简单起见,n 是“2”的幂,例如 1, 2, 4, 8, 16 , etc。我想用(n/2) 元素将它分成两部分。分离条件是 lowest absolute difference between sum of all elements in two arrays 例如,如果我有这个数组 (9,2,5,3,6,1,4,7) ,它将与这些数组 (9,5,1,3)(6,7,4,2) 分开。第一个数组元素的总和是18,第二个数组元素的总和是19,差异是1,这两个数组是答案,但是像(9,5,4,2)(7,6,3,1)这样的两个数组不是答案,因为元素总和的差异是4,我们找到了1。所以4 不是最小的区别。如何解决这个问题? 谢谢。

【问题讨论】:

  • PS,为什么n的限制是2的幂?要拥有两个大小完全相同的子数组,您只需要 n 是偶数,而不是假设它是 2 的幂。
  • @amit 我认识这个朋友。但我认为在接下来的步骤中它将把它分成另一个部分,所以在这种情况下它需要一个 n
  • @therealprashant 不完全是骗子,因为这里对两个子集的基数有额外的限制(大小相同)
  • 其实我应该说参考 而不是重复

标签: c arrays algorithm


【解决方案1】:

这是Partition Problem,不幸的是NP-Hard

但是,由于您的数字是整数,如果它们相对较小,则存在使用 Dynamic Programming 的伪多项式 O(W*n^2) 解(其中 W 是所有元素的总和)。

这个想法是创建大小为(W/2+1)*(n+1)*(n/2+1)的DP矩阵,基于以下递归公式:

D(0,i,0) = true
D(0,i,k) = false     k != 0
D(x,i,k) = false     x < 0
D(x,0,k) = false     x > 0
D(x,i,0) = false     x > 0
D(x,i,k) = D(x,i-1,k) OR D(x-arr[i], i-1,k-1)

上面给出了一个 3d 矩阵,其中每个条目 D(x,i,k) 表示是否有一个子集正好包含 k 元素,总和为 x,并使用第一个 i 元素作为候选。

一旦你有了这个矩阵,你只需要找到最高的x(小于SUM/2)使得D(x,n,n/2) = true

稍后,您可以通过返回表格并在每个步骤中“追溯”您的选择来获得相关子集。 This thread 处理一个非常相似的问题。


对于小型集合,还有一种简单的蛮力解决方案的替代方案,它基本上将数组分成所有可能的一半((2n)!/(n!*n!) 其中的一半),并从中挑选出最好的一个。

【讨论】:

    猜你喜欢
    • 2020-07-04
    • 1970-01-01
    • 1970-01-01
    • 2019-12-07
    • 1970-01-01
    • 1970-01-01
    • 2019-09-22
    相关资源
    最近更新 更多