如何使用贪心算法找到最接近给定序列的非递减序列?


20

a1,,an0laibi0lbib i O n 4max(|a1b1|,,|anbn|)biO(nl4)

老实说,我根本不知道如何开始解决这个问题。在我看来,这似乎是一个动态编程问题,但这位教授说,应该使用贪婪算法解决该问题。如果有人可以给我一点点提示就可以指出正确的方向,那将不胜感激。

Answers:


9

让我们从以下观察开始:

max表示序列a_1,...,a_n的最大值a1,...,an,令min表示其最小值。如果a1=max,则选择b1=b2=...=bn=(max+min)/2是最佳的。

为什么会这样呢?好吧,由于序列从最大值开始,所以我们要么选择大,然后与序列的最小值较大(因为任何后续必须大于或等于),要么我们选择小并遭受偏差。平均值使最大偏差最小。b i b 1 b 1 m a xb1bib1b1max

现在,我们可以尝试概括此观察结果,以用于一般序列。例如,我们可以将任何序列划分为子序列,从而每个序列都以各自子序列的最大值开始。a1,...,an

示例:分为,和。2 6 4 1 5 2 8 7 5 1 (2,6,4,1,5,2,8,7,5,1)(2)(6,4,1,5,2)(8,7,5,1)

给定这种划分,我们现在可以分别求解每个子序列,并获得的赋值,但是这可能违反了非递减条件。可以解决此问题而不会失去最优性。bi

请注意,最后一个子序列始终包含整个序列的最大(否则,后面会有另一个子序列)。令是我们分配给的值。现在,要实现非递减,我们从的背面开始,然后一直向前。如果大于,我们只需设置。如果较小,我们保留。然后,我们继续比较与,依此类推。请注意,将任何降低到瓦特1瓦特2瓦特ķ ķ 瓦特1w k w k w k 1 w k w k 1= w k w k 2 w k 1 w i w i + 1maxw1,w2,...,wkkw1,...,wkwkwk1wkwk1:=wkwk2wk1wiwi+1永远不会增加偏差,因为分配给的子序列中的最大值始终小于分配给的子序列中的最大值。瓦特+ 1wiwi+1

我认为这种算法应该是正确的。关于运行时间,关键步骤是计算子序列的递增最大值,这在?不知道从哪里有助于。O(n)l


2

我将在这里大声思考,只是按照您给出的提示进行操作。让我们转到最初的提示,说是您应该首先尝试的。我可以想到一个有时间的贪婪算法。O(nl)

时间复杂度的部分意味着您可以保留每个值的每次出现次数的列表。那就是创建一个的集合,该集合跟踪集合中每个的计数。您可以通过扫描输入序列一次来创建初始化列表。l0..lCount=C0,,Cll

您可以在扫描此列表以获取最大值和最小值。如果要用此中点填充的整个列表,则您的方差就是该值与最大值/最小值的差。基本上这是最坏的情况,我们称之为。O(l)bbw

因此,从左到。您都可以从删除此元素,并在获得的最小值/最大值。现在我们可以贪婪了。我们不选择因为这会强制剩余的整个列表(以满足非递减要求)并因此增加差异。我们可以选择的最小值是。如果在可接受的范围内,则选择它;如果低于该范围,则使用最小值。给定已知约束,这的方差最小。biCountb[i+1]b[n]O(l)bi>bwb[i1]aibi

这只是一个想法,也许我很幸运,它为您指明了正确的方向。该算法可能不起作用(它对我的一些简单测试有效),但确实与给出的提示匹配,因此也许很有用。如果正确的话,很容易看出部分可以确定地下降到,甚至更进一步,我不确定。O(l)O(logl)


2

这是教授的解决方案,他称之为“减少”:对于每个从0l的,如果我们知道偏差小于或等于i,则尝试构造一个解决方案。可以找到解决方案的第一个i是最小偏差。给定O n 时间的偏差,我们可以找到一个解决方案。因此运行时间为O n l 。然后,代替使用线性搜索,我们可以使用二进制搜索来确定可以解决的最小偏差。这样可以将运行时间减少到O n log li0liiO(n)O(nl),其满足的要求 ø Ñ 4 O(nlogl)O(nl4)


4
所以是个把戏...但是我更感兴趣“给定O(n)时间的偏差,我们可以找到一个解决方案” ..那不是最有趣的部分吗?O(nl4)
jmad 2012年

@jmad鉴于,对于每个Ĵ,取b Ĵ作为其至少一样大的所有先前的最低值b ķ,并且其是不超过远离一个Ĵ。如果我们找不到这样的值,那意味着什么?这意味着先前b 超过比大一个Ĵ。所以,以前的一个牛逼超过2 比我的大一个Ĵ。所以我的价值是不可能的。如果你通过得到ñijbjbkiajbtiajat2iajin值不会像这样卡住,您已经找到了在时间O n )内没有回溯的的解决方案。iO(n)
jwg

O(n log l)将强烈提示您需要在0到l的范围内进行一些二进制搜索。
gnasher729

0

我认为这应该在O(n)中可行。

采取类似的问题:给定,1≤i≤n且d≥0,以非降序找到b i,使得| a ib i | d对所有的i,或表明这是不可能的。可以在O(n)中完成,使用二进制搜索可以在O(n log 1)中解决原始问题。aibi|aibi|d

现在假设存在i≤Ĵ使得A_I - a_j> 2d中,那么就没有溶液(因为)。biaid,bjaj+d<ai2d+d=aidbi

但是,如果对于所有i≤j,a_i-a_j≤2d,那么我认为总会找到一个解决方案。因此,我们要做的就是找到所有i≤j的m = max(a_i-a_j),然后选择d = floor((m + 1)/ 2)。该最大值可以在O(n)中找到。


有趣的想法!我可以相信类似的方法可能会奏效,但答案的结尾似乎有很大的差距,我很难填补细节。你有,如果证明所有Ĵ然后向溶液中总是存在?更重要的是,我们如何找到它?最初的问题说我们必须找到b i。即使我们假设存在解决方案,我也很难看到如何找到对应的b i。您能详细说明一下吗?aiaj2dijbibi
DW
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.