动态编程:使用括号最大化算术表达式的值

时间:2014-07-14 19:38:27

标签: algorithm dynamic-programming

这是一段时间问我的面试问题:

  

假设你有一个表达式E = x1 y1 x2 y2 .... yn-1 xn。

     

其中Xi属于自然数,Yi属于{+,*}

     

你需要括号,以便最大化E?

的值

我能够在动态编程的方向上思考并且可以将它与matrix chain multiplication problem相关联,但是却坚持导出这个的精确递归关系。

此外,后续问题让我感到困惑:

  

让我们将Yi改为{+, - ,*,/},然后如何最大化E?现在添加%   该集合中的运算符......然后如何最大化E?

关于如何为此解决和构建解决方案的解释将非常棒。

2 个答案:

答案 0 :(得分:4)

我认为与矩阵乘法算法的相同关系将起作用。

我们尝试计算的功能是

F(i,j) = maximum number that can be computed using Xi ... Xj

基本情况是我们有一个数字:

F(i,i) = Xi

递归情况是用括号括起来的两个子表达式之间的操作:

F(i,j) = for k = i,j-1, maximize
    F(i,k) Yk F(k+1, j)

我认为贪婪地最大化数字应该有效,因为对于乘法和加法而不是正数,我们希望两个操作数都尽可能大。

如果我们允许除法,那么我们希望第二个操作数尽可能小以最大化结果。在这种情况下,您不仅需要计算F,还需要计算一个类似的G,以最大限度地缩短区间内的值。

如果我们允许减法,那么我们需要考虑正数和负数。如果你跟踪正数,最小正数,最大负数和最小负数,我认为你应该能够得到你需要的任何值。也许有一种替代方案需要较少的计算。

我没有停下来思考%的含义。首先,它是如何使用/的非整数结果?

答案 1 :(得分:1)

通过动态编程,您可以计算Xi和Xj之间可能的最大表达式,假设您将外部parantheses放在Xi和Xj周围。您的动态编程递归涉及迭代所有可以在假定的外部parantheses中插入一组相邻的parantheses的方法,并从所有子案例的最大可能值计算最大可能值。如果你有n个术语,这就天真地给出一个O(n ^ 3)时间算法。

当你允许除法和减法时,事情变得更加复杂,与另一个答案所暗示的相反。例如,如果你想最大化并且你有分裂那么你想要在最大值为正时使分子最大化并且在保持正值时使分母尽可能接近1,或者如果最小值为负则你想要最小化分子并且在保持负面的同时使分母尽可能接近-1。如果分子和分母的符号不匹配,那么您希望最小化分子的大小并最大化分母的大小。最后一个案例并不难,但前两个案例似乎非常重要。如果你被允许使用所有4个算术运算,你如何在保持符号的同时尽可能接近1或-1?这甚至可能是NP难问题,特别是如果你也包括模数运算。