【发布时间】:2016-02-14 08:42:29
【问题描述】:
我被要求提供一个 动态 算法,该算法将采用偶数(正数和负数)的序列并执行以下操作:
每个“转”两个数字被选择相乘。该算法只能访问序列的任一端。但是,如果选择的第一个数字是最左边的数字,则 第二个数字可以是最右边的数字,也可以是新的最左边的数字(因为旧的最左边的数字已经“删除/选择”),反之亦然。该程序的目标是找出每轮选择的两个数字的乘积的最大总和。
示例:
序列:{ 10, 4, 20, -5, 0, 7 }
最佳结果:7*10 + 0*-5 + 4*20 = 150
我的进步:
我一直在尝试找到一种动态方法,但运气不佳。我已经能够推断出该程序基本上只允许每次将结束数字乘以“相邻”数字,并且目标是将最小可能的数字乘以最小可能的数字(导致双负乘法 - 一个正数,或可达到的最小最小数),并且每次都继续应用此规则直到完成。相比之下,这条规则也适用于相反的方向——每次将最大可能数字乘以最大可能数字。也许最好的方法是同时应用这两种方法?我不确定,正如我所提到的,我在为这个问题实施算法时运气不佳。
【问题讨论】:
-
编写一个递归算法来检查每一种可能性非常容易;但是,这将多次检查相同的序列:在您的示例中,有三种不同的方式可以到达最后一步 {20,-5}。为避免计算三次,您应先计算短子数组的结果,存储结果,然后使用它来求解数组的较大部分。
-
对于 20 个数字的数组,简单的递归算法需要 29,524 次递归,而从小部分到大部分的算法(另见 dfb 的答案)只需要计算 100 个案例(19 + 17 + ... + 1)。
标签: algorithm recursion dynamic numbers divide-and-conquer