从给定列表中选择最小数字以得出总和N(允许重复)

时间:2018-08-28 08:56:22

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

如何找到从列表中取出的元素可以求和成给定数量的最小数量的方法(N) 例如,如果list = [1,3,7,4]且N = 14,则函数应返回2作为7 + 7 = 14 同样,如果N = 11,则函数应返回2作为7 + 4 = 11。我想我已经找到了算法,但是无法在代码中实现它。 请使用Python,因为这是我了解的唯一语言(目前) 抱歉!

2 个答案:

答案 0 :(得分:0)

如果您将算法包含在伪代码中会很有帮助-它看起来非常像Python:-)

另一方面:您的第一个操作是将列表(7)中的一项与列表(2)之外的一项相乘,而第二个运算则为7 + 4-列表中的两个值。

使用哪种操作或使用哪些项目(从列表内还是不包括列表)是否有限制?

答案 1 :(得分:0)

由于您在问题中提到了动态编程,并且说您已经弄清楚了算法,因此我将只包含用Python编写的基本表格方法的实现,而无需过多理论。 这个想法是要有一个表格结构,我们将用它来计算所需的所有可能值,而不必多次进行相同的计算。 基本公式将尝试对列表中的值求和,直到达到每个目标值的目标值为止。

它应该可以工作,但是您当然可以进行一些优化,例如尝试排序列表和/或寻找红利,以构建更小的表并更快地终止。

代码如下:

import sys

# num_list : list of numbers
# value: value for which we want to get the minimum number of addends

def min_sum(num_list, value):

    list_len = len(num_list)

    # We will use the tipycal dynamic programming table construct
    # the key of the list will be the sum value we want, 
    # and the value will be the
    # minimum number of items to sum

    # Base case value = 0, first element of the list is zero   
    value_table = [0]

    # Initialize all table values to MAX
    # for range i use value+1 because python range doesn't include the end
    # number
    for i in range(1, value+1):
        value_table.append(sys.maxsize);

    # try every combination that is smaller than <value>
    for i in range(1, value+1):
        for j in range(0, list_len):
            if (num_list[j] <= i):
                  tmp = value_table[i-num_list[j]]
                  if ((tmp != sys.maxsize) and (tmp + 1 < value_table[i])):
                      value_table[i] = tmp + 1

    return value_table[value]



## TEST ##
num_list = [1,3,16,5,3]
value = 22
print("Min Sum: ",min_sum(num_list,value)) # Outputs 3