达到目标号码

时间:2015-01-14 01:32:02

标签: python numbers

我是初学者,如果这个问题听起来很愚蠢/不清楚或非常容易,请耐心等待。

如何将数字列表添加到一起以达到目标数字或尽可能接近?例如,这里是一个数字列表:(2,3,4,7,20,25),目标= 105.结果应为:(25,25,25,25,3,2)。给定数字的顺序很重要;始终从列表中的最大数字开始并按顺序添加它们以接近给定值,因此它将选择要测试的下一个数字。结果也可能是(20,20,20,20,25),在这种情况下不正确,因为它不遵循数字的顺序。该算法只有跳过下一个数字才能跳过,否则无法跳转。

最佳M

4 个答案:

答案 0 :(得分:1)

l=(2,3,4,7,20,25)
goal = 105

a=max(l)
b=0
res=[]
while b<=goal-24:
    b+=a
    t=goal-b
    res.append(a)
    g=0
    for x in l:
        g+=x
        if g==t:
            res.append(x)
            res.append(g-x)
            break

print (res)

输出:

>>> 
[25, 25, 25, 25, 3, 2]
>>> 

我发现这个解决方案,然而,真让我烦恼:-)!棘手的部分是while b<=goal-24:,其他代码是基本的Python。

答案 1 :(得分:0)

这是对的吗?我现在没有时间进行测试。

def solution(numbers, goal):
    curr = 0
    numbers = sorted(numbers)
    while curr < goal:
        if not numbers: break
        n = numbers.pop()
        while n + curr <= goal:
            yield n
            curr += n

list(solution([2,3,4,7,20,25], 105))

结果:

[25, 25, 25, 25, 4]

答案 2 :(得分:0)

如果速度不是问题,这是最终正确的答案:

import itertools

def change_maker(coins, amount):
    for r in range(amount//max(coins), amount//min(coins)+1):
        possibilities = (combo for combo in itertools.combinations_with_replacement(coins, r) if sum(combo) == amount)
        try:
            result = next(possibilities)
        except StopIteration:
            # no solution with current r
            continue
        else:
            return result

这将始终返回最佳结果,但在某些情况下可以计算ABSURD组合数量。

样本:

>>> coins = (2, 3, 4, 7, 20, 25)
>>> goals = 105
>>> print(change_maker(coins, goal))
[20, 20, 20, 20, 25]

答案 3 :(得分:0)

我会采用动态编程方法:

def fewest_items_closest_sum_with_repetition(items, goal):
    """
    Given an array of items
      where each item is 0 < item <= goal
      and each item can be used 0 to many times

    Find the highest achievable sum <= goal

    Return any shortest (fewest items) sequence
      which adds to that sum.
    """
    assert goal >= 0, "Invalid goal"
    # remove any duplicate or invalid items
    items = set(item for item in items if 0 < item <= goal)
    # sort descending (work with largest values first)
    items = sorted(items, reverse=True)

    # start with the no-item sequence
    best   = {0: []}
    active = {0: []}
    # while we have further seeds to work from
    while active:
        nactive = {}
        for item in items:
            for total, seq in active.items():
                # find next achievable sum
                ntotal = total + item
                # if it is a valid subgoal and has not already been found
                if (ntotal <= goal and ntotal not in best):
                    # save it
                    best[ntotal] = nactive[ntotal] = [item] + seq
                    if ntotal == goal:
                        # best possible solution has been found!
                        break
        active = nactive

    # return the best solution found
    return best[max(best)]

然后像

一样运行
>>> fewest_items_closest_sum_with_repetition([2,3,4,7,20,25], 105)
[25, 20, 20, 20, 20]

>>> fewest_items_closest_sum_with_repetition((40,79), 80)
[40, 40]