के हस्ताक्षर आप गतिशील प्रोग्रामिंग के साथ इस हल कर सकते हैं बदलने के लिए प्रत्येक संख्या का चयन कर सकते हैं। (परिवर्तन की न्यूनतम संख्या के लिए मानचित्रण इस राशि तक पहुँचने के लिए) के लिए सभी संभव आंशिक योग का एक नक्शा रखें, और फिर इसे एक समय में एक नंबर अपडेट,
यहाँ एक संक्षिप्त पायथन समाधान है:
def signs(nums):
xs = {nums[0]: 0}
for num in nums[1:]:
ys = dict()
for d, k in xs.iteritems():
for cost, n in enumerate([num, -num]):
ys[d+n] = min(ys.get(d+n, 1e100), k+cost)
xs = ys
return xs.get(0, -1)
print signs([1, 1, -4, -4, -4, -2, -2])
में सिद्धांत में सबसे बुरी स्थिति में घातीय जटिलता है (क्योंकि आंशिक रकम की संख्या प्रत्येक चरण में दोगुनी हो सकती है)। हालांकि, अगर (यहां के रूप में) दिए गए नंबर हमेशा छोटे स्याही होते हैं, तो आंशिक रकम की संख्या रैखिक रूप से बढ़ती है, और कार्यक्रम ओ (एन^2) समय में काम करता है।
कुछ हद तक अधिक अनुकूलित संस्करण एक dict के बजाय क्रमबद्ध सरणी (subtotal, लागत) का उपयोग करता है। कोई आंशिक रकम छोड़ सकता है जो बहुत बड़े या बहुत छोटे होते हैं (यह मानते हुए 0 पर समाप्त होना असंभव हो जाता है कि शेष शेष तत्व -300 और +300 के बीच हैं)। यह लगभग दोगुनी तेजी से चलता है, और अधिकतम गति के लिए पायथन की तुलना में निम्न-स्तर की भाषा में बंदरगाह के लिए एक अधिक प्राकृतिक कार्यान्वयन है।
def merge(xs, num):
i = j = 0
ci = 0 if num >= 0 else 1
cj = 0 if num < 0 else 1
num = abs(num)
while j < len(xs):
if xs[i][0] + num < xs[j][0] - num:
yield (xs[i][0] + num, xs[i][1] + ci)
i += 1
elif xs[i][0] + num > xs[j][0] - num:
yield (xs[j][0] - num, xs[j][1] + cj)
j += 1
else:
yield (xs[i][0] + num, min(xs[i][1] + ci, xs[j][1] + cj))
i += 1
j += 1
while i < len(xs):
yield (xs[i][0] + num, xs[i][1] + ci)
i += 1
def signs2(nums):
xs = [(nums[0], 0)]
for i in xrange(1, len(nums)):
limit = (len(nums) - 1 - i) * 300
xs = [x for x in merge(xs, nums[i]) if -limit <= x[0] <= limit]
for x, c in xs:
if x == 0: return c
return -1
print signs2([1, 1, -4, -4, -4, -2, -2])
एक तरह से बैक ट्रैकिंग के मामले में खोज के पेड़ छँटाई करने को एहसास है कि '4 हो सकता है - 4' रूप में ही है' - 4 + 4'। –
कुल समानता प्राप्त करें, यदि यह विषम प्रिंट -1 है। – Vesper
नहीं, संख्याएं '1 <= x <300' – user2660964