考虑您拥有 N 值的问题,并且您需要计算使用 N 美元钞票可以将 [1,2,5,10,20,50,100] 美元加起来的方式有多少。

考虑经典的 DP 解决方案:

C = [1,2,5,10,20,50,100]

def comb(p):
    if p==0:
        return 1
    c = 0
    for x in C:
        if x <= p:
            c += comb(p-x)
    return c

它不影响相加部分的顺序。例如, comb(4) 将产生 5 个结果: [1,1,1,1],[2,1,1],[1,2,1],[1,1,2],[2,2] 而实际上有 3 个结果( [2,1,1],[1,2,1],[1,1,2] 都是相同的)。

计算这个问题的 DP 习语是什么? (不欢迎非优雅的解决方案,例如生成所有可能的解决方案并删除重复项)

最佳答案

您不应该每次都从头开始,但最多从每个深度开始。
这意味着您必须传递两个参数,开始和剩余总数。

C = [1,5,10,20,50,100]

def comb(p,start=0):
    if p==0:
        return 1
    c = 0
    for i,x in enumerate(C[start:]):
        if x <= p:
            c += comb(p-x,i+start)
    return c

或等价物(它可能更具可读性)
C = [1,5,10,20,50,100]

def comb(p,start=0):
    if p==0:
        return 1
    c = 0
    for i in range(start,len(C)):
        x=C[i]
        if x <= p:
            c += comb(p-x,i)
    return c

关于algorithm - 组合的动态规划习语,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3444144/

10-10 01:45