如何使用递归最大化和最小化数学表达式?

时间:2015-04-02 22:03:10

标签: algorithm recursion dynamic-programming

表达式由两个运算符之一' *'分隔的数字(0-9)组成。和' +'。角色之间没有空格。

示例:1+2*3+4*5

我们需要通过在适当的位置使用括号来找出我们可以获得的最大值和最小值。

最大值:105 = (1+2)*(3+4)*5

最低价值:27 = 1+2*3+4*5

我正在寻找一种递归方式来做到这一点?任何想法都将不胜感激。

1 个答案:

答案 0 :(得分:3)

最小化

解决方案的主要思想:不要考虑如何添加括号,而是考虑哪个操作是最后一个。让我们写一个递归函数minimize(expr)。它该怎么办?如果给出一个数字,它应该返回它。否则,我们可以遍历其中的所有运算符,在运算符的左侧和右侧调用minimize部分表达式并组合结果。现在我们只需要选择最小的值。

这是一些伪代码:

int minimize(string expr)
    if isNumber(expr) then // If it is one number, return it.
        return value(expr)
    int res = infinity
    for int i <- 0 .. lenght expr - 1
        if expr[i] == '+' then
            res = min(res, minimize(expr[0 .. i - 1]) +
                           minimize(expr[i + 1 .. length expr - 1])
        if expr[i] == '*' then
            res = min(res, minimize(expr[0 .. i - 1]) * 
                           minimize(expr[i + 1 .. length expr - 1])
    return res

最大化

几乎相同,但我们应该在每一步采取最大值而不是最小值。

为什么这是正确的?当我们乘以并添加非负数时,操作数越大(越小),结果越大(越小)。

我们还可以使用memoization来避免重复计算同一表达式的结果两次(或更多次)并获得多项式时间复杂度。