【问题标题】:Find a sum equal or greater than given target using only numbers from set仅使用集合中的数字查找等于或大于给定目标的总和
【发布时间】:2025-12-13 15:40:02
【问题描述】:

示例 1:

商店销售啤酒,可用包装为每包 6 和 10 个单位。客户输入 26,算法回复 26,因为 26 = 10 + 10 + 6。

示例 2:

销售香料,可用包为 0.6、1.5 和 3。目标值 = 5。算法返回值 5.1,因为它是最接近的大于使用包(3、1.5、0.6)可能实现的目标的数字。

我需要一个能提示该数字的 Java 方法。

Bin packing problem 中描述了类似的算法,但它不适合我。 我试过了,当它返回的数字小于目标时,我再次运行它并增加了目标数。但是当包的数量很大时效率不高。

我需要几乎相同的算法,但最近的数字相等或更大。

类似问题:Find if a number is a possible sum of two or more numbers in a given set - python

【问题讨论】:

  • 你给了我一些我已经知道的提示。我的目标是获得一种可以正常工作的纯方法,因此您的答案并不比我在谷歌上搜索的其他答案更好。而你的建议:“简单算法”需要很多时间。
  • “纯方法”是什么意思?我们提供的是一个伪多项式的最优解,它可能尽可能好,因为这个问题是 NP 难的。另外,将来,请在问题中包含您已经知道的内容。否则我们怎么知道你需要知道什么?
  • 如果您有不清楚的地方,您可以随时在答案上写 cmets 要求澄清。

标签: java algorithm


【解决方案1】:

首先让我们将这个问题简化为整数而不是实数,否则我们将无法从中获得快速的最优算法。例如,让我们将所有数字乘以 100,然后将其四舍五入到下一个整数。假设我们有项目大小 x1、...、xn 和目标大小 Y。我们想要最小化这个值

k1 x1 + ... + kn xn - Y

条件下

(1) ki 是一个非正整数,对于所有 n ≥ i ≥ 1

(2) k1 x1 + ... + kn xn - Y≥0

对此的一个简单算法是提出一系列问题,例如

  1. 我们能否实现k1 x1 + ... + kn xn = Y + 0?
  2. 我们能否实现k1 x1 + ... + kn xn = Y + 1?
  3. 我们能否实现k1 x1 + ... + kn xn = Y + z?
  4. 等。随着 z 的增加

直到我们得到“是”的答案。所有这些问题都是Knapsack 问题的实例,其权重设置等于项目的值。好消息是,如果我们可以为 z 建立一个上限,我们可以一次解决所有这些问题。很容易证明存在 z ≤ Y 的解,除非所有 xi 都大于 Y,在这种情况下,解决方案就是选择最小的xi

所以让我们使用pseudopolynomial dynamic programming approach 来解决背包问题:让 f(i,j) 为 1 iif 我们可以达到总物品大小 j 与第一个>i 个项目 (x1, ..., xi)。我们有复发

f(0,0) = 1
f(0,j) = 0   for all j > 0
f(i,j) = f(i - 1, j) or f(i - 1, j - x_i) or f(i - 1, j - 2 * x_i) ...

我们可以在O(n * Y)时间和O(Y)空间解决这个DP数组。结果将是第一个 j ≥ Yf(n, j) = 1

有一些技术细节留给读者练习:

  • 如何在 Java 中实现这一点
  • 如果需要,如何重建解决方案。这可以使用 DP 数组在 O(n) 时间内完成(但我们需要 O(n * Y) 空间来记住整个事情)。

【讨论】:

    【解决方案2】:

    你想解决整数规划问题 min(ct) s.t. ct >= T, c >= 0 其中 T 是您的目标重量,c 是一个非负整数向量,指定每个包裹要购买多少,t 是指定每个包裹重量的向量。您可以使用另一个答案指出的动态规划来解决这个问题,或者,如果您的权重和目标权重太大,那么您可以使用通用整数规划求解器,这些求解器多年来经过高度优化,可以在实践中提供良好的速度性能.

    【讨论】: