- 论坛徽章:
- 0
|
本帖最后由 lovai 于 2014-08-26 20:13 编辑
回复 431# vbs100
类似如下解法的:首先随机划分出两个子集,然后交换能使得和差降低(最多)的两个元素,直到找不到能降低的。
这是典型的爬山法,需要考虑有没有可能极值不是最值的情况。
当a和b长度不一样时,极值可能不是最值,如极值局面{1, 101, 50}和{70, 80},这时需要一次性选择并交换两对元素才能达到最优解delta=0。
当a和b长度一样时[本题],极值仍可能不是最值,不过得由于存在对称解,这种情况只可能出现在N>3的情况,如{2 , 3, 101, 50}和{0 , 4, 80, 70},这时也需要一次性选择并交换两对元素才能达到最优解delta=0(sum(a)=155)。而上述算法的输出是sum(A)=156 sum(B)=154 sum(A)-sum(B)=2,显然是陷入局部极小值了。
下面给出“低效”但正确的DP解法:
抽象为问题:集合S划分为大小为n和n-|S|的两个子集,使得子集和之差最小。
DP:f(w, i):到i为止,和为w的所有子集的长度的列表,
Ans = minw{abs(sum(S)/2 – w) | n in f(w, |S|)}
最坏复杂度O(W*|S|*|S|) |
|