【问题标题】:How do I maximise and minimize the mathematical expression using recursion?如何使用递归最大化和最小化数学表达式?
【发布时间】:2015-04-02 22:03:09
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

  • 我们应该使用的括号数量是固定的吗?
  • 1+(2*3)+4*5 和其他变种也是最低要求
  • @MrGreen:不,它不是固定的。您可以根据需要添加任意数量。问题是你能达到的最大值是多少。
  • @KarolyHorvath:在所有情况下最小值都是 27 并不重要。

标签: algorithm recursion dynamic-programming


【解决方案1】:

最小化

解决方案的主要思想:与其考虑如何添加括号,不如考虑最后一个操作是哪个操作。让我们写一个递归函数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 来避免重复计算同一表达式的结果两次(或多次)并获得多项式时间复杂度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-28
    相关资源
    最近更新 更多