这是问题所在:
你有两个长度相等的数组A和B.你必须将它们分成两组P和Q,这样: (1)他们的差异被最小化。 (2)如果A [i]进入P或Q中的一个,B [i]应该进入另一个。
以下是实际问题的链接:http://opc.iarcs.org.in/index.php/problems/EQGIFTS
这是我的逻辑(解决实际问题):
如果输入是:a b c d e f g,值列表和索引 a,b,c,d,e,f分别为0,1,2,3,4,5
如果t是a,b,c,d,e,f,g的索引,则程序检查t和i这样 那个:[t]>的值在[t-i]处的值,从t = 5开始,和i = 1,并将i的值增加1并减小t的值 由1。
一旦找到匹配,就会交换两个索引的值 并从[t-1]开始对值进行排序。 结果值列表是输出。
我不知道这个算法有什么问题,但它为所有测试用例产生了错误的答案。 我知道它可以使用动态编程来解决,并且它是分区问题的变体。但我不知道如何更改分区算法来解决这个问题。
答案 0 :(得分:3)
将问题减少到分区问题
为每个D[i] = B[i] - A[i]
创建第三个数组i
。
现在问题是数组D
上的经典partition problem,您可以使用其DP解决方案来获得伪多项式时间解决方案。
正确性证明:
如果D
(sum(D_1) = sum(D_2)
)上有解决方案,则选择i_1,...,i_k
D_1
并j_1,...,j_m
选择D_2
(并且每个索引都在i或j中),这样:
sum(D[i's]) = sum(D[j's])
从构造中,它意味着:
sum(B[i]-A[i]) = sum(B[j]-A[j]) (for each relevant i's,j's)
因此:
sum(B[i's]) - sum(A[i's]) = sum (B[j's]) - sum(A[j's])
由此:
sum(B[i's]) + sum(A[j's]) = sum(B[j's]) + sum(A[i's])
正是我们想要的,因为每个“索引”被分配给两个部分,一个部分得到一个B而另一部分得到A.
另一个方向是相似的。
QED
问题的复杂性:
问题仍然是NP-Hard,简单的减少:
给定分区问题(S=[a_1,a_2,...,a_n]
)的实例,创建此问题的实例:
A=S, B=[0,...,0]
很容易看出,为这个问题提供最佳解决方案的相同解决方案将是原始分区问题所需的分区,因此问题是NP-Hard。