数组中的总和不大于 k

问题描述 投票:0回答:1

给定一个整数数组和一个整数 k

从给定数组中查找小于或等于 k

的最大可能总和
  • 示例:

    数组 = 7,6,9,11 k = 25

  • 答案:

    24

  • 说明:

    可能的组合:
    尺寸 1 = (7),(6),(9),(11)
    尺寸 2 = (6,7), (6,9), (6,11), (7,9), (7,11), (9,11)
    尺寸 3 = (6,7,9), (6,7,11), (6,9,11), (7,9,11)
    尺寸 4:(6,7,9,11)

    在这些可能的组合中,最大且小于或等于 k=25 的项之和为 (6,7,11)=24

  • 限制:

    数组的大小为1到40
    k 的值为 1 到 109
    数组中项目的值为 1 到 109

我正在使用post中提到的代码:

def largest_subset(items, k):
    res = 0

    # We can form subset with value 0 from empty set,
    # items[0], items[0...1], items[0...2]
    arr = [[True] * (len(items) + 1)]

    for i in range(1, k + 1):
        # Subset with value i can't be formed from empty set
        cur = [False] * (len(items) + 1)

        for j, val in enumerate(items, 1):
            # cur[j] is True if we can form a set with value of i from
            # items[0...j-1]
            # There are two possibilities
            # - Set can be formed already without even considering item[j-1]
            # - There is a subset with value i - val formed from items[0...j-2]
            cur[j] = cur[j-1] or ((i >= val) and arr[i-val][j-1])
        if cur[-1]:
            # If subset with value of i can be formed store
            # it as current result
            res = i

        arr.append(cur)
    return res

它适用于小范围的输入,但是当程序的输入很大时,代码会在以下行失败:

cur = [False] * (len(items) + 1)
内存错误

我还尝试了另一篇帖子

def subset_sum(vals, target=0):
    sums = {0: [()]}  # key=sum, value=list of subsets for the sum
    if target in sums:
        yield from sums[target]  # annoying base case
    for val in vals:
        items = sums.items()  # don't change dict size during iteration
        sums = dict(items)
        for prev_sum, prev_subsets in items:
            sum_ = prev_sum + val
            subsets = [s + (val,) for s in prev_subsets]
            sums[sum_] = sums.get(sum_, []) + subsets
            if sum_ <= target:
                yield from subsets

它也失败并出现相同的错误消息:

subsets = [s + (val,) for s in prev_subsets]

解决这个问题的正确方法是什么。

python java algorithm time-complexity space-complexity
1个回答
0
投票

修改这个答案:不能由数组中的数字之和形成的最小数字

使用位向量来完成此操作。

从空位向量开始 b。然后对于数组中的每个元素 x,执行以下操作:

b = b | << x | 2^(x-1)

需要明确的是,第i个元素被设置为1来表示数字i,并且| x 将第 x 个元素设置为 1。

在执行上述步骤 (b = b | ...) 时,在 k 位之后截断修改后的 b,因为我们不关心生成更大的值。

处理完数组后,b 中某个集合位的最大索引就是您的答案(从右数,从 1 开始)。

在此示例中,对于 [4,13,2,3,1],我们可以将除 11 和 12 之外的所有值设置为 23。

b=0 过程4:b = b | <<4 | 1000 = 1000 process 13: b = b | b<<13 | 1000000000000 = 10001000000001000 process 2: b = b | b<<2 | 10 = 1010101000000101010 process 3: b = b | b<<3 | 100 = 1011111101000101111110 process 1: b = b | b<<1 | 1 = 11111111111001111111111 First zero: position 11.

© www.soinside.com 2019 - 2024. All rights reserved.