什么时候加上了绝对值……
带绝对值就是 Partition Problem 了,有一个伪多项式的 DP 算法,思路大概是这样的:
var cache = ...; function P(a, j, l, s) { // a[0..j] 中有长度为 l 且总和为 s 的子集吗? if(cache.has(j, l, s)) return cache.find(j, l, s) // 缓存 if(l === 0 && s === 0) return cache.save(j, l, s, true); if(l === 0 && s !== 0 || j === 0 && l > 0 || j === 0 && s !== 0) return cache.save(j, l, s, false); return cache.save(j, l, s, P(a, j - 1, l, s) || P(a, j - 1, l - 1, s - a[j - 1])) } for(var s = Math.floor((sum(a) + sum(b)) / 2); s >= 0; s--){ if(P(a.concat(b), n * 2, n, s)) { ... } }
不带绝对值的话
先要说清楚定义,因为如果只能交换 ab 中的对应项,那么很简单的贪心法就能解决;如果可以多次任意交换,那么就是排序完切割;如果是一次交换若干对的话,是 2n×2n 的二分图最佳匹配,用 KM。