If this problem is to be solvable; then sum(ALL)/3
must be an integer. Any solution must have SUM(J) + SUM(K) = SUM(I) + sum(ALL)/3
. This represents a solution to the 2-partition problem over concat(ALL, {sum(ALL)/3})
.
You say you have a 2-partition implementation: use it to solve that problem. Then (at least) one of the two partitions will contain the number sum(ALL)/3
- remove the number from that partion, and you've found I
. For the other partition, run 2-partition again, to split J
from K
; after all, J
and K
must be equal in sum themselves.
Edit: This solution is probably incorrect - the 2-partition of the concatenated set will have several solutions (at least one for each of I, J, K) - however, if there are other solutions, then the "other side" may not consist of the union of two of I, J, K, and may not be splittable at all. You'll need to actually think, I fear :-).
Try 2: Iterate over the multiset, maintaining the following map: R(i,j,k) :: Boolean
which represents the fact whether up to the current iteration the numbers permit division into three multisets that have sums i
, j
, k
. I.e., for any R(i,j,k)
and next number n
in the next state R'
it holds that R'(i+n,j,k)
and R'(i,j+n,k)
and R'(i,j,k+n)
. Note that the complexity (as per the excersize) depends on the magnitude of the input numbers; this is a pseudo-polynomialtime algorithm. Nikita's solution is conceptually similar but more efficient than this solution since it doesn't track the third set's sum: that's unnecessary since you can trivially compute it.
runs in time poly- nomial in n and
, I'd presume. – Yandell