使用DP的python中的子集和

时间:2018-04-12 03:45:23

标签: python python-3.x dynamic-programming backtracking

我跟随此link为子集问题编写DP解决方案。

def subsetSum(input, target):
    row, col = len(input)+1, target+1
    db = [[False] * col] * row
    for i in range(row):
        db[i][0] = True

    for i in range(1, row):
        for j in range(1, col):
            db[i][j]=db[i-1][j]
            if db[i][j]==False and j>=input[i-1]:
                db[i][j] = db[i-1][j-input[i-1]]

    return db[i][j]

target = 5
input = [1,3,9,2]
subsetSum(input, target)

有趣的是,经过" j ", db [i-1] 的每次迭代(我们引用值的前一行)也正在更新。我真的失去了在这里发生的事情。请建议。

请为打印的陈述找到link

1 个答案:

答案 0 :(得分:1)

问题出在这一行 db = [[False] * col] * row。 当您使用*运算符时,会生成原始列表的副本,该副本引用原始列表。

考虑以下示例:

l = [[1]*5]*3
print(l) # prints [[1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]
l[0][0] = 0
print(l) # prints [[0, 1, 1, 1, 1], [0, 1, 1, 1, 1], [0, 1, 1, 1, 1]]

每个内部列表引用同一个对象。因此,当第一个列表的第一个元素发生变化时,所有列表似乎都会发生变化。

要解决此问题,您可以使用列表理解:

l = [[1]*5 for _ in range(3)]
print(l) # prints [[1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]
l[0][0] = 0
print(l) # prints [[0, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]

具体而言,您可以使用以下内容将作业替换为db

db = [[False]*col for _ in range(row)]