Python—求和大于或等于某个值的数字的组合

Python—求和大于或等于某个值的数字的组合,python,permutation,dynamic-programming,number-theory,Python,Permutation,Dynamic Programming,Number Theory,最近有人向我提出了一个用Python回答的面试问题——给定一个数量-值对列表,找到一组值的最佳组合,这些值的总和与提供的某些值一样接近,至少与提供的值一样大 例如,假设:[(1,$5),(3,$10),(2,$15)],并且期望值为$36,则答案将是[(2,$15),(1,$10)]或[(1,$15),(2,$10),(1,$5)]。原因是40美元是可以实现的最小金额,大于或等于36美元,这是实现该金额的两种方法 我被难住了。有人有解决办法吗?数字太小了,你可以用蛮力来解决: In []: no

最近有人向我提出了一个用Python回答的面试问题——给定一个数量-值对列表,找到一组值的最佳组合,这些值的总和与提供的某些值一样接近,至少与提供的值一样大

例如,假设:[(1,$5),(3,$10),(2,$15)],并且期望值为$36,则答案将是[(2,$15),(1,$10)]或[(1,$15),(2,$10),(1,$5)]。原因是40美元是可以实现的最小金额,大于或等于36美元,这是实现该金额的两种方法


我被难住了。有人有解决办法吗?

数字太小了,你可以用蛮力来解决:

In []:
notes = [(1, 5), (3, 10), (2, 15)]
wallet = [n for a, b in notes for n in [b]*a]
combs = {sum(x): x for i in range(1, len(wallet)) for x in it.combinations(wallet, i)}

target = 36
for i in sorted(combs):
    if i >= target:
        break
i, combs[i]

Out[]:
(40, (5, 10, 10, 15))
您可以对所有组合进行扩展,只需将
combs
字典理解替换为:

combs = {}
for i in range(1, len(wallet)):
    for x in it.combinations(wallet, i):
        combs.setdefault(sum(x), set()).add(x)

...
i, combs[i]

Out[]:
(40, {(5, 10, 10, 15), (10, 15, 15)})

您可以尝试
itertools.combines
查找给定数量-值对的所有组合,然后只取最小值