小编典典

在重叠间隔序列中找到最大和的算法

algorithm

我要解决的问题在数字行上有一个间隔列表,每个间隔都有一个预定义的分数。我需要返回最大可能的总成绩。

问题是间隔重叠,在重叠间隔中我只能使用一个。这是一个例子。

Intervals   - Score  
   0- 5     -  15  
   4- 9     -  18  
  10-15     -  12  
   8-21     -  19  
  25-30     -  25

在此,间隔0-5、4-9和8-21重叠。
间隔10-15和8-21也重叠。
最大和为55(18 + 12 + 25)。

重要的是要在这里注意,我们选择的第一批重叠间隔的间隔4-9,即使它没有三者中最高的得分。

这是因为选择间隔8-21将阻止我们以后再使用间隔10-15,从而减少了总和(在这种情况下,总和将为19 + 25 = 44)。

我正在寻找此问题的O(nlogn)或O(n)解决方案。我认为可以使用动态编程,但我可能是错的。有人可以提出可以解决问题的解决方案/算法吗?

编辑:间隔没有特定的顺序。


阅读 269

收藏
2020-07-28

共1个答案

小编典典

这是间隔调度的加权变化; 它可以O(N log N)通过动态编程解决

设一个间隔g(start, stop, score),然后按排序stop。为了简单起见,让我们现在假设所有stop都是唯一的。

让我们best[i]成为允许使用时可获得的最佳分数g[1], ..., g[i]。当然,我们不必全部使用它们,而且通常也不能,因为我们使用的间隔子集必须不重叠。

  • 显然best[0] = 0。也就是说,由于我们不能使用任何间隔,因此我们可以获得的最佳分数是0。
  • 对于任何一个1 <= k <= N,我们都有:
    • best[k] = max( best[k-1], best[j] + g[k].score ),在哪里
    • j是最大的索引,使得g[j].stop < g[k].startj可以为零)

也就是说,考虑到我们被允许使用g[1], ... g[k],我们可以做的最好的事情就是对这两个选项进行更好的评分:

  • 不包括在内g[k]。因此,此选项的分数是best[k-1]
    • …因为那是我们可以做到的最好 g[1], ... g[k-1]
  • 我们包括g[k],在左边,我们会尽力处理所有不与之重叠的基因g[k],即all g[1], ..., g[j],其中g[j].stop < g[k].startj都尽可能大。因此,此选项的分数是best[j] + g[k].score

(请注意上式中体现的动态编程的最佳子结构和重叠子问题组件)。

这个问题的总体答案是best[N],即,当我们允许使用所有基因时,我们可以得到的最高分数。糟糕,我说过基因吗?我的意思是间隔。

这是O(N log N)因为:

  • 对所有间隔进行排序 O(N log N)
  • 寻找j每一个kO(log N)使用二进制搜索

如果几个基因可以具有相同的stop值,那么什么都没有改变:您仍然必须搜索最右边的j。在例如Python中,使用会很容易bisect_right。在Java中,标准库二进制搜索不能保证在有关联的情况下返回哪个索引,因此您可以(在许多选项中)进行线性搜索(以获取O(N)最坏情况的性能)或其他一系列二进制搜​​索来查找最正确的索引。

糟糕,我又说了基因?我的意思是间隔。

`

2020-07-28