用给定和计算最小子集

时间:2014-04-19 10:37:42

标签: algorithm scala subset subset-sum

2 个答案:

答案 0 :(得分:3)

制作一个完整的总和列表是不必要的,使用BigInt是浪费的 - 一个Long最多可以容纳9.2e18,并且你被承诺只会出现1e15。 (事实上​​,我认为1e15被选中,因此即使Double也可以保持答案而不会损失精确度。)

此外,您可以对基元使用快速排序,而不是像_ > _这样的慢速泛型排序,最终会对整数进行装箱。所以:

val arr = {
  val in = readLine().split(' ').map(_.toInt)
  java.util.Arrays.sort(in)
  in
}

然后,使用累加器(Long将会这样做):

var sum = 0L

并使用while循环搜索答案,请记住最大的元素是最后一个,所以你想从最后开始:

var i = arr.length-1
while (i >= 0 && sum < t) {
  sum += arr(i)
  i -= 1
}

现在你只需要在用完元素之前检查你是成功还是失败:

val answer = {
  if (i < 0) -1
  else arr.length - i - 1
}

答案 1 :(得分:0)

这里是(使用O(N)存储器并且使用O(N log N)时间)

scala> import math.{Ordering => Ord}
import math.{Ordering=>Ord}

scala> def search(src: Seq[Long], dst: Seq[Long]): Seq[Int] = {
     |   val cum = src.sorted(Ord.Long.reverse).scanLeft(0L)(_ + _)
     |   dst.map{ v => cum.indexWhere(x => x >= v) }
     | }
search: (src: Seq[Long], dst: Seq[Long])Seq[Int]

scala> search(Seq(4, 12, 8, 10), Seq(4, 13, 30, 100))
res6: Seq[Int] = List(1, 2, 3, -1)