贪婪算法的正确性

时间:2015-03-11 21:25:31

标签: algorithm greedy

  

在(正)整数的非递减序列中,enter image description here时可以删除两个元素。可以从此序列最多删除多少对?

所以我想到了以下解决方案:

  • 我按照给定的顺序分成两部分(第一部分和第二部分)。
  • 分别为每个iterator-it_first:= 0和it_second:= 0分配。 count:= 0
  • 当it_second!= second.length
    • if 2 * first [it_first]< = second [it_second]
      • count ++,it_first ++,it_second ++
    • 否则
      • it_second ++
  • count就是答案

示例:

count:= 0

[1,5,8,10,12,13,15,24] - > 第一次:= [1,5,8,10],第二次:= [12,13,15,24]

  1. 2 * 1?< 12 - > true,count ++,it_first ++ and it_second ++

  2. 2 * 5?< 13 - > true,count ++,it_first ++ and it_second ++

  3. 2 * 8?< 15 - > false,it_second ++

  4. 8?< 24-> true,count ++ it_second到达最后一个元素--END。

  5. count == 3

  6. 线性复杂度(最坏的情况是没有这样的元素被删除.n / 2个元素与n / 2个元素相比)。 所以我缺少的部分是算法的“正确性” - 我已经阅读了贪婪的算法证明 - 但主要是树木,我找不到类比。任何帮助,将不胜感激。谢谢!

    修改 正确性我的意思是:  * 有用  *它不能更快​​地完成(以logn或常量)

    我想放一些图形,但由于声誉点< 10 - 我不能。 (我的意思是一开始就有一种乳胶;))

2 个答案:

答案 0 :(得分:3)

  1. 正确性:

    • 假设可以删除的最大对数为k。声明:有一个最优解决方案,其中所有对的第一个元素是数组的k个最小元素。 证明:我将证明可以将任何解决方案转换为包含第一个k元素的解决方案作为所有对的第一个元素。

      1. 我们假设我们有两对(a, b)(c, d)a <= b <= c <= d2 * a <= b2 * c <= d。在这种情况下,对(a, c)(b, d)也是有效的。现在我们有a <= c <= b <= d。因此,我们总是能够以这样的方式变换对,即任何一对中的第一个元素不大于任何一对中的第二个元素。

      2. 当我们有这个属性时,我们可以简单地用数组中最小元素的所有对的所有第一个元素中的最小元素替换,所有第一个元素中的第二个最小元素 - 具有第二个最小元素数组等,而不会使任何一对无效。

    • 现在我们知道有一个包含k个最小元素的最佳解决方案。很明显,我们不能通过采用适合每个元素的最小的未使用元素(使其更大,只能减少下一个元素的答案)来使答案变得更糟。因此,这个解决方案是正确的。

    • 关于阵列长度为奇数的情况的注释:中间元素的位置与第一个或第二个半径无关。在上半场它没用(下半场没有足够的元素)。如果我们把它放到下半场,它是无用的两个(让我们假设我们接受了它。这意味着有#34;自由空间&#34;在下半场的某个地方。因此,我们可以转移一些元素由一个摆脱它)。

  2. 时间复杂度方面的最优性:此解决方案的时间复杂度为O(n)。在最糟糕的情况下,我们无法在没有读取整个输入的情况下找到答案,并且阅读时间已经O(n)。因此,该算法是最优的。

答案 1 :(得分:1)

假设你的方法。指数从0开始。

一般表示:

    第一部分的
  • end_1 = floor(N/2)边界(包括)。

迭代时表示:

    第一部分中的
  • i索引,第二部分中的j索引
  • 此时的最佳解决方案sol(i,j)(使用前面的算法),
  • 仍然在(i,j)点之后最佳配对的对,即来自 (i+1,j+1)向前rem(i,j)(可以使用后面的算法计算),
  • 最终最优解可以表示为任何点的函数sol(i,j) + rem(i,j)

观察#1 :当使用[0, i]范围内的所有点进行算法时,不使用[end_1+1, j]范围内的某些点(我们跳过{{1}不大的笨蛋)。从后面做算法时,不使用某些a(j)点,并且使用了所有[i+1, end_1]点(我们跳过[j+1, N]不够小)。

观察#2 a(i),因为rem(i,j) >= rem(i,j+1),其中rem(i,j) = rem(i,j+1) + M可以是M0,具体取决于我们是否可以将1a(j)范围内的一些未使用的元素配对。

论据(通过矛盾):让我们假设[i+1, end_1]并且不配对2*a(i) <= a(j)a(i)至少提供最佳解决方案。通过算法,我们接下来会尝试配对a(j)a(i)。时间:

  • a(j+1)(见上文),
  • rem(i,j) >= rem(i,j+1)(因为我们没有配对sol(i,j+1) = sol(i,j)a(i)

我们得到的a(j)与假设相矛盾。