贪心算法还是动态编程?

时间:2016-01-12 22:31:26

标签: algorithm dynamic-programming greedy

给出了列表l = [x_1,...,x_n]。列表中的每个元素都是某块木头的长度。要粘合长度为a和b的两块木材,你需要最大(a,b)胶水。粘合后,你得到一块长度为a + b的木头。计算粘合所有碎片的最小胶水量。

你觉得贪心算法在这里有效吗?我想不出任何一个例子。说贪婪的算法我的意思是:取两片最小长度,粘上它们,直到所有的部分被胶合。使用某个优先级队列,可以在O(n log n)复杂度中完成。

这有用吗?如果没有,请给我一些清单l的例子,它可以用比贪婪算法更少的胶水粘合。

3 个答案:

答案 0 :(得分:4)

贪心算法并不总是最佳的。一个反例是[1,2,2,3],贪婪算法将使用10个单位的胶水,最佳将使用9个单位。

贪心算法:

1-2 = 2 glue
2-3 = 3 glue
3-5 = 5 glue
---------------
total = 10 glue

最优:

2-2 = 2 glue
1-3 = 3 glue
4-4 = 4 glue
--------------
total = 9 glue

动态编程。

答案 1 :(得分:0)

看起来有没有最优贪婪算法没有通用动态编程解决方案。我认为它是 NP-hard ,我解释原因。

让我们分析问题。我们有N个元素。让这个集合分成两个带有X和Y元素的子集。首先,我们将X子集中的所有元素粘合在一起,然后以某种方式粘合Y子集中的所有元素(如除法和征服技术)。在最后的粘合中,我们应该粘合代表X和Y子集的2个元素。在最后的胶合中我们需要的胶水量是多少?当X元素和Y元素之和的差异最小时!我们将这个问题表示为递归的分区问题,这是NP hard本身

答案 2 :(得分:0)

贪婪算法肯定不会像Briguy37所说的那样起作用,因为贪婪的局部最优解在这种情况下不会为您提供全局最优解。

但是,此问题是NP类问题,无法使用动态编程解决。您需要采用蛮力方法,这将花费大量时间。请看下面的树,其中一个问题是我们从大小1开始的。显然,我们看不到任何逻辑上重叠的子问题,可以将其概括为一种动态编程方法。

Tree for starting with size 1