【问题标题】:number combination algorithm数组合算法
【发布时间】:2009-04-12 22:50:36
【问题描述】:

编写一个函数,给定一串数字和一个目标值,打印在数字之间放置 + 和 * 的位置,以便它们完全结合到目标值。请注意,答案可能不止一个,您打印哪一个都没有关系。

例子:

"1231231234",11353 -> "12*3+1+23*123*4" 
"3456237490",1185  -> "3*4*56+2+3*7+490" 
"3456237490",9191  -> "no solution"

【问题讨论】:

    标签: c algorithm


    【解决方案1】:

    如果您有 N 位值,则 + 或 * 运算符有 N-1 个可能的插槽。所以蛮力,有 3^(N-1) 种可能性。测试所有这些都是低效的。

    但是

    您的示例都是 10 位数字。 3 ^ 9 = 19683,所以蛮力很好!没有必要变得更高级。

    因此,您需要做的就是遍历所有 19683 个案例,每次都为该案例构建一个字符串,然后评估表达式。评估表达式是一项简单的任务。迭代很简单(只需使用递增值,您可以通过 (i%3) 读取第一个插槽的状态,这给您“无运算符”“+”或“*”,第二个插槽的状态是(i /3)%3,第三个槽的状态为(i/9)%3,以此类推)

    即使使用粗略的解析代码,CPU 也很快。

    蛮力选项在大约 20 位数字后开始变得丑陋,你必须改得更聪明。

    【讨论】:

    • +1 用于估计从蛮力到聪明的转换。
    【解决方案2】:

    如果这是针对游戏程序员的职位,请不要使用蛮力方法。我这样做了,但几年前失败了。后来从内部人员那里听说动态编程方法是得到这份工作的方法。

    【讨论】:

      【解决方案3】:

      这可以通过回溯或动态规划来解决。

      【讨论】:

        【解决方案4】:

        “更聪明”的方法(使用动态编程)基本上是这样的:

        对于原始字符串的每个子字符串,找出它可以创建的所有可能值。 (例如,在您的第一个示例中,“12”可以变为 1+2=3 或 1*2=2)

        可能有很多不同的组合,但其中很多都是重复的。 (此外,您应该忽略所有大于目标的组合)。

        因此,当您添加“+”或“*”时,您可以将其设想为组合字符串的两个子字符串。 (并且由于每个子字符串都有可能的值,因此您可以查看这种组合是否可行)

        这些值可以类似地生成:尝试以所有可能的方式拆分子字符串,并在子字符串的每一半中组合不同的值。

        因此,“状态”的总数类似于 |S|^2 * 目标 - 对于您的示例情况,它比蛮力方法更糟糕。但是如果你有一个长度为 1000 的字符串,目标是 5000,那么这个问题可以通过动态规划来解决。

        【讨论】:

          【解决方案5】:

          Google Code Jam 去年(在Round 1C 中)有这个问题的扩展版本,称为丑陋数字。当扩展到大量数字时,您可以访问该链接并单击“竞赛分析”以了解该问题的一些方法。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-01-31
            • 1970-01-01
            相关资源
            最近更新 更多