我正在练习动态编程,而且我正在努力调试我的代码。我们的想法是在给定数字列表的情况下查找是否可以求和。这是我的代码:
a = [2,3,7,8,10]
sum = 11
b = list(range(1, sum+1))
m = [[False for z in range(len(b))] for i in range(len(a))]
for i, x in enumerate(b):
for j, y in enumerate(a):
if x==y:
m[j][i]=True
elif y<x:
m[j][i] = m[j-1][i]
else:
m[j][i] = m[j-1][i] or m[j-i][y-x]
for i, n in enumerate(m):
print(a[i], n)
这是输出:
2 [False, True, False, False, False, False, False, False, False, False, False]
3 [False, True, True, False, False, False, False, False, False, False, False]
7 [False, True, True, False, True, True, True, False, False, False, False]
8 [False, True, True, False, True, True, True, True, False, False, False]
10 [False, True, True, False, True, True, True, True, True, True, False]
据我所知,在我的else语句中,该算法应该上升1行,然后查看x和y的差异,并检查该槽是否可行。因此,例如在最明显的情况下,最后一行中的最后一个元素。这将是10(y)-11(x),它应该一直回到它上面的行上的索引1,这正如我们所知道的那样。不完全确定我做错了什么,理解这一点的任何帮助都将非常感激。
答案 0 :(得分:4)
鉴于您只提供正值,我并不完全理解为什么您需要二维列表。您只需使用1d列表:
coins = [2,3,7,8,10]
sum = 11
接下来,我们初始化列表possible
,说明是否有可能获得某个值。我们将possible[0]
设置为True
,因为这笔款项可以在没有硬币的情况下完成。
possible = [False for _ in range(sum+1)]
possible[0] = True
现在,您遍历每个硬币,并在列表上进行迭代,并且#34;升级&#34;尽可能的价值:
for coin in coins:
for i in range(sum-coin,-1,-1):
if possible[i]:
possible[i+coin] = True
之后,列表possible
会显示从0
到(包括sum
)的每个值,是否可以构建它。因此,如果possible[sum]
为True
,则可以构建sum
。
对于给定的coins
和sum
,可获得:
>>> possible
[True, False, True, True, False, True, False, True, True, True, True, True]
所以价值0
,2
,3
,5
,7
,8
,9
,{{1 },10
可以用硬币构建。
您还可以通过稍微修改代码来跟踪硬币:
11
现在可能看起来像:
possible = [None for _ in range(sum+1)]
possible[0] = []
for coin in coins:
for i in range(sum-coin,-1,-1):
if possible[i] is not None:
possible[i+coin] = possible[i]+[coin]
所以>>> possible
[[], None, [2], [3], None, [2, 3], None, [7], [8], [2, 7], [10], [3, 8]]
可以用硬币0
构建(没有硬币); []
可以使用2
(一个值为[2]
的硬币),2
3
,[3]
5
,等