我有两个间隔序列。
第一个是固定的和不重叠的,所以类似于:
[1..10], [12..15], [23..56], [72..89], ...
第二个不是固定的,所以它只是间隔长度的有序列表:
[7, 2, 5, 26, ...]
手头的任务是:
很简单的例子:
[25..26], [58..68], [74..76], [78..86]
[10, 12]
最佳解决方案是将长度10的间隔设置为[58..68],将长度12的间隔设置为[74..86],这样只会将数字25,26和77放在一个列表中但不是另一个。
我唯一想到的似乎是温和有用的是,如果我按顺序放下间隔,我知道我已经创造了多少'惩罚',所以我有一个上限得分,这意味着我有一个可接受的启发式,我可以做A *搜索,而不是看整个树。但是,总的数字范围从0到大约34M,所以我想要更好的东西。
任何帮助都会很热!
答案 0 :(得分:0)
好的,这是一个经过深思熟虑的答案。它应该在多项式时间内工作,但我没有费心去检查索引是什么。有可能获得比这里概述的答案更好的索引。详细信息留给读者阅读:-)我希望它不太清楚。
我将解决方案的得分定义为两个间隔列表中出现的整数数。设f(i,m)是仅使用前i个区间长度可以获得的最高分数,条件是没有任何区间超过m。对于fixed i,函数f本质上是从整数到整数的有界子集的(非严格)递增函数。因此:
这意味着可以使用有限数据结构表示f(i,m)的所有值(仍然考虑i的固定值)。
现在让F(i)为表示f(i,m)的所有值的数据结构的值。我声称,给定F(i),可以计算F(i + 1)。要做到这一点,我们只需要为所有x回答以下问题:如果我将新区间放在x,我可以得到的最佳解决方案有多好?但我们知道这是什么 - 它只是f(i,x)+我们从这个间隔得到的分数。
因此,如果n是第二个列表中的间隔数,则最佳解的分数将为F(n)。
要真正找到解决方案,您可以从此向后工作。
你知道什么是你能得到的最好成绩。说它是s_0。然后将最后一个区间尽可能地放在最左边,但条件是它允许你得分s_0。也就是说,找到最小的m,使得f(n,m)= s_0;并将间隔设置为仅保持在m的界限内。
然后,让s_1成为你需要从所有其他间隔获得的分数,以获得总共s_0。将最后一个间隔放在尽可能最远的位置,但条件是您仍然可以得到s_1。也就是说,找到最小的m,使得f(n,m)= s_1;并将间隔设置为仅保持在m的界限内。
等等......