Reputation: 191
So i have this problem: given a set of two dimensional tuples on the form {x,y}, where all x and y are positive integers, decide if it is possible to take out a subset so that:
√( (∑x)² + (∑y)²) = A²
For a positive integer A.
Example, given
[{2,2},{1,4},{1,2}] and A = 5
one solution is {2,2} and {1,2} since 3² + 4² = 5²
It is allowed to reuse the same tuple multiple times.
The goal is th solve this with dynamic programming. I was looking at http://www.geeksforgeeks.org/dynamic-programming-subset-sum-problem/, a dynamic solution of a subset sum problem; however the difference here is that all the terms are squared and 2d, so i don't believe that method works
Upvotes: 2
Views: 792
Reputation: 10565
There may be faster options, but a simple PD is:
T(X, Y, i): Is it possible to achieve the ∑x = X and ∑y = Y using up to the i-th term?
T(0, 0, 0) = TRUE
T(X, Y, i) = FALSE if X<0 or Y<0 or (i==0 and X!=0 and Y!=0)
T(X, Y, i) = T(X-V[i].X, Y-V[i].Y, i) or T(X, Y, i-1)
Then, scan every pair (X, Y), to find one that X²+Y²=A² and T(X, Y, n) is true (where n is the size of the set).
Here is a non-optimized recursive version just to prove the concept (in Python):
def T(V, x, y, i):
if x==0 and y==0 and i==0: return []
if x<0 or y<0 or i<=0: return None
answer = T(V, x-V[i-1][0], y-V[i-1][1], i)
if answer is not None: return answer + [V[i-1]]
return T(V, x, y, i-1)
def solve(V, A):
for x in range(A):
for y in range(A):
if x*x+y*y==A*A:
answer = T(V, x, y, len(V))
if answer:
return answer
return None
print(solve([(2,2),(1,4),(1,2)], 5))
It prints one possible solution:
[(2, 2), (1, 2)]
Upvotes: 1