[英]Subset sum variation, dynamic programming
我正在尝试解决经典的子集总和问题,但需要注意的是子集的总和应该尽可能接近tgt
而不会超过它。 这是我的递归,它找出数字子集的总和与数字之间的距离,它按预期工作。 inf
承认如果总和超过tgt
,我们不想要它:
def targetSum(S, i, tgt):
# your code here
k = len(S)
#base case
if tgt < 0:
return float('inf')
if i >= k and tgt >= 0:
return tgt
else:
return min(targetSum(S, i+1, tgt-S[i]), targetSum(S, i+1, tgt))
对于备忘录表,以下是说明:
使用 [(,)] 形式的备忘录表记住您的重复,其中 0≤≤() 和 0≤≤。 在代码中添加 function lookupMemoTable 可能会有所帮助,以帮助您处理 <0 的查找。 假设目标满足 tgt >= 0。
我无法弄清楚 function lookupMemoTable (这可能是我的问题),但这是我的代码到目前为止,它适用于一些示例(a1 = [1, 2, 3, 4, 5, 10],tgt = 15)但不是全部(a3= [11, 23, 37, 48, 94, 152, 230, 312, 339, 413], tgt = 457):
def memoTargetSum(S, tgt):
k = len(S)
assert tgt >= 0
## Fill in base case for T[(i,j)] where i == k
T = {} # Memo table initialized as empty dictionary
for j in range(tgt+1):
T[(k,j)] = j
#print(T[(k,j)], j)
#def lookupMemoTable
for i in range(k-1, -1, -1):
for j in range(tgt, -1, -1):
if T[(i + 1, j)]-S[i] < 0:
T[(i,j)] = T[(i + 1, j)]
else:
T[(i,j)] = T[(i + 1, j)]-S[i]
print(T)
return T
在此先感谢您的帮助!
我认为你不必完全改变整个 function。 该表用于存储以后可以再次使用的计算。 您可以将每个递归调用的结果添加到您的dict
。 如果使用相同的输入再次调用 function ,您可以简单地返回dict
内的值。 例如,像这样:
a3 = [11, 23, 37, 48, 94, 152, 230, 312, 339, 413]
tgt = 457
mem = {}
def targetSum(S, i, tgt):
k = len(S)
# If calculation with this input is already computed return result from mem
if (i,tgt) in mem:
print('used mem')
return mem[(i,tgt)]
if tgt < 0:
return float('inf')
if i >= k and tgt >= 0:
return tgt
else:
minimum = min(targetSum(S, i+1, tgt-S[i]), targetSum(S, i+1, tgt))
# Store result of current calculation in mem if needed again later
mem[(i,tgt)] = minimum
return minimum
targetSum(a3, 0, tgt)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.