查找在给定限制下可以从商店收集的最大重量

时间:2018-10-22 16:53:34

标签: algorithm backtracking

我在SAP实验室的分班考试中遇到了这个问题:

今天是您的生日,因此您会得到一个带有固定空格“ S ”的皮包。您可以去商店挑选喜欢的物品,放在袋子里。该商店有“ n ”个项目,每个项目都占用一个空间 s [i] 。您必须找出可以填充的最大空间

例如,假设您的行李限制为 S = 15 ,而商店有 10 件商品,尺寸为 [1、7、3、5, 4,10,6,15,15,20,8] 。现在,您可以通过 [1、7、3、4],[7、3、5],[15],[5、10]等各种方式填充 15 空间 em>等。所以您返回 15

注意:项目大小存在怪异。除 15 以外的所有项目均遵循以下规则:*对于所有 i,j,,要么 size [i]> = 2 * size [j] +1 size [j]> = 2 * size [i] +1 ,如果 i≠j 。*

约束:

1 <= n <= 60

1 <=大小[i] <= 10 ^ 17

1 <= S <= 10 ^ 18

示例: S = 9,n = 5,大小= [1、7、4、4、10]。

输出: 8 。您无法以任何方式完全填充 9 空间。您可以使用 [1,7] [4,4] 填充8个空格。

1 个答案:

答案 0 :(得分:0)

我们称x遵循该规则的元素。请注意,对于这组元素,我们有一些不错的属性:

  • 以升序给出x,sum(x [i..j])
  • 要求解最大和<= k,只需以降序排序,并在可能的情况下从k x [i]中减去。原始k-剩下的k是解。假设元素已经排序,则为O(| x |)。

获取此集合的一种方法是迭代按大小升序排序的项目,并在满足以下条件时添加到集合:

  • 集合没有任何元素或
  • 当前元素> = 2 * size [lastElementAdded] + 1

现在,我们最多剩下15个不遵循此规则的项目。因此,我们不能像以前那样使用有效的解决方案。对于每件商品,我们都可以考虑将其放入或不放入袋中。这导致2 ^ 15个可能的总和。对于这些总和,我们可以为遵循规则的元素运行方法。

总体复杂度:2 ^ 15 *(n-15)。对于n = 60,应在不到一秒钟的时间内解决。

作为练习:通过使用累加和和二进制搜索,可以将其降低到2 ^ 15 * log2(n-15)。