细分最多的点算法分析

时间:2018-10-25 06:31:20

标签: algorithm dynamic-programming

我们定义x1,x2,...,x_n为点(数字)的序列,[s_i,t_i]为1≤i≤n的n个段的集合。如果s_i≤x_j≤t_i,则点x_j在线段i内。我想找到积分最高的细分。

现在要解决这个问题,我想我们可以根据s对x和间隔进行排序。保留一个单独的数组T,使T [i] =段i中的最大点。将此数组中的所有值初始化为0。然后,对于每个x,检查所有符合约束的间隔,并相应地增加T [i]。

在最坏的情况下,这可能需要O(n ^ 2)。但是我觉得我在这里有很多多余之处。如何提高效率?

1 个答案:

答案 0 :(得分:2)

请澄清一下,如果问题是一维的,则Xx_1x_n)中的点是数字,而线段是间隔。

您可以通过对X进行排序并使用结果索引来轻松解决此问题。通过找到两个相应的索引[s, t]i,可以有效地计算段j中的点数。查找(使用二进制搜索或最有效的方法)i,使x_i < s <= x_(i+1),和j,使x_j <= t < x_(j+1)。注意不等式(如果st可能在X中)。 [s, t]中的点数等于j-i

如果s < x_1t > x_n是可能的,只需在X的两端附加一个点(最小和最大)。

这具有O(n log n)的复杂度,受排序算法限制。如果您可以使用诸如计数排序之类的方法来将值用作数组的索引(或将键作为多集的索引),那么您可以通过做更多的工作来改进它。

S为包含所有段s的每个t和每个[s, t]的点集。这个想法是为X构建索引数组(有点像用于计数排序)。

首先,以AA[x in X] = 1的形式构建数组A[x not in X] = 0。然后,再次遍历以构建数组A_less,以使A_less[i]等于所有A[j]j < i的和。
例如,如果A = [1, 0, 0, 1, 0, 1, 0],则A_less = [0, 1, 1, 1, 2, 2, 3]。您可以使用一个简单的计数器来构建此数组。

您现在可以直接引用此数组以获取值小于或等于另一个的点数。在前面的示例中,X中显然有三个点,其值分别为0、3和5。通过引用A_less,您可以知道存在A_less[4] = 2个点的值较小等于或等于4。

类似地,构建A_less_equal使得A_less_equal[i]等于所有A[j]j <= i的总和。使用相同的示例A_less_equal = [1, 1, 1, 2, 2, 3, 3]

现在,对于任何段[s, t],您都可以通过计算A_less_equal[t] - A_less[s]获得其包含的点数。所有这些都具有复杂性O(n)

如果您的点不是整数(至少不容易用作索引),那么您仍然可以使用相同的想法,将数组替换为排序集,其键是X中的每个值或S(您需要在S中添加值才能在末尾查找它们。)