Answers:
让我们从以下观察开始:
令表示序列a_1,...,a_n的最大值,令表示其最小值。如果,则选择是最佳的。
为什么会这样呢?好吧,由于序列从最大值开始,所以我们要么选择大,然后与序列的最小值较大(因为任何后续必须大于或等于),要么我们选择小并遭受偏差。平均值使最大偏差最小。b i b 1 b 1 m a x
现在,我们可以尝试概括此观察结果,以用于一般序列。例如,我们可以将任何序列划分为子序列,从而每个序列都以各自子序列的最大值开始。
示例:分为,和。(2 )(6 ,4 ,1 ,5 ,2 )(8 ,7 ,5 ,1 )
给定这种划分,我们现在可以分别求解每个子序列,并获得的赋值,但是这可能违反了非递减条件。可以解决此问题而不会失去最优性。
请注意,最后一个子序列始终包含整个序列的最大(否则,后面会有另一个子序列)。令是我们分配给的值。现在,要实现非递减,我们从的背面开始,然后一直向前。如果大于,我们只需设置。如果较小,我们保留。然后,我们继续比较与,依此类推。请注意,将任何降低到瓦特1,瓦特2,。。。,瓦特ķ ķ 瓦特1,。。。,w k w k w k − 1 w k w k − 1:= w k w k − 2 w k − 1 w i w i + 1永远不会增加偏差,因为分配给的子序列中的最大值始终小于分配给的子序列中的最大值。瓦特我+ 1
我认为这种算法应该是正确的。关于运行时间,关键步骤是计算子序列的递增最大值,这在?不知道从哪里有助于。升
我将在这里大声思考,只是按照您给出的提示进行操作。让我们转到最初的提示,说是您应该首先尝试的。我可以想到一个有时间的贪婪算法。
时间复杂度的部分意味着您可以保留每个值的每次出现次数的列表。那就是创建一个的集合,该集合跟踪集合中每个的计数。您可以通过扫描输入序列一次来创建初始化列表。
您可以在扫描此列表以获取最大值和最小值。如果要用此中点填充的整个列表,则您的方差就是该值与最大值/最小值的差。基本上这是最坏的情况,我们称之为。
因此,从左到。您都可以从删除此元素,并在获得的最小值/最大值。现在我们可以贪婪了。我们不选择因为这会强制剩余的整个列表(以满足非递减要求)并因此增加差异。我们可以选择的最小值是。如果在可接受的范围内,则选择它;如果低于该范围,则使用最小值。给定已知约束,这的方差最小。
这只是一个想法,也许我很幸运,它为您指明了正确的方向。该算法可能不起作用(它对我的一些简单测试有效),但确实与给出的提示匹配,因此也许很有用。如果正确的话,很容易看出部分可以确定地下降到,甚至更进一步,我不确定。
这是教授的解决方案,他称之为“减少”:对于每个从0到l的,如果我们知道偏差小于或等于i,则尝试构造一个解决方案。可以找到解决方案的第一个i是最小偏差。给定O (n )时间的偏差,我们可以找到一个解决方案。因此运行时间为O (n l )。然后,代替使用线性搜索,我们可以使用二进制搜索来确定可以解决的最小偏差。这样可以将运行时间减少到O (n log l,其满足的要求 ø (Ñ 4 √。
我认为这应该在O(n)中可行。
采取类似的问题:给定,1≤i≤n且d≥0,以非降序找到b i,使得| a i − b i | ≤ d对所有的i,或表明这是不可能的。可以在O(n)中完成,使用二进制搜索可以在O(n log 1)中解决原始问题。
现在假设存在i≤Ĵ使得A_I - a_j> 2d中,那么就没有溶液(因为)。
但是,如果对于所有i≤j,a_i-a_j≤2d,那么我认为总会找到一个解决方案。因此,我们要做的就是找到所有i≤j的m = max(a_i-a_j),然后选择d = floor((m + 1)/ 2)。该最大值可以在O(n)中找到。