【问题标题】:Dynamic programming: find the subset with product of all members is equals to given number动态规划:找到所有成员乘积等于给定数字的子集
【发布时间】:2015-02-16 09:16:32
【问题描述】:

我会找到解决这个问题的算法。

输入:n 个整数和数字 k 组成的数组

我们必须从数组中找到一组数字,集合中所有这些数字的乘积等于k是

我想,我必须为这个任务使用动态编程。但我不知道如何使用它。

【问题讨论】:

标签: algorithm dynamic-programming


【解决方案1】:

这类似于子集求和问题,您需要找到 sum 为值k 的子集。

既然你的问题有一个解决方案(你有一个子集S,乘法是k)当且仅当你对集合中的每个 x 都有一个 log(x) 的子集,总和是 @ 987654325@(同一个子集,每个元素都有log),问题几乎相同。

但是,通常使用的 DP 解决方案对于求和非常有效,因为元素的总和最终不会很大,而乘法则可以。您也不能在所有元素上使用 log 并“使用它”,因为数字不会是整数 - 子集总和的 DP 解决方案需要整数才能处理。

但是,您可以使用Top-Down DP (memoization) 部分解决此问题。这相当简单,按如下方式完成:

existenceOfSubset(set, product, map):
    if (product== 1):
           return true
    if (set.isEmpty()):
           return false
    if (map.containsKey(product)):
           return map.get(product)
    first = set.getFirst()
    set = set.removeFirst()
    solution = existenceOfSubset(set,product,map) OR (product%first == 0?existenceOfSubset(set,product/first,map):false) //recursive step for two possibilities
    map.put(product,solution  //memoize
    set.addFirst(first) //clean up
    return solution

使用existenceOfSubset(set,product,new HashMap())调用

【讨论】:

  • 它是 memoization,没有 r.
  • @IVlad 谢谢,不知道。
  • 有了自上而下的DP,我们真的需要日志吗?难道我们的递归步骤不能不除以那个元素并尽可能地除以吗? (你的代码中仍然有一个部门,我真的不明白)。
  • @IVlad 这非常简单,就像子集和的自上而下一样,但是使用除法而不是减法。此解决方案不涉及任何日志。 log 只是在解释为什么它是子集和的变体,但在算法本身中却无处可寻。
  • 哦,我以为您的代码假定您正在使用元素的日志。在这种情况下,您不应该仅在sum % first == 0 时使用sum / first 调用该函数吗? 3 / 2 = 1,但这不应该返回 true。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-05
  • 1970-01-01
  • 1970-01-01
  • 2019-01-23
  • 2017-02-06
  • 2014-12-15
  • 1970-01-01
相关资源
最近更新 更多