修正硬币变化的伪多项式时间算法

时间:2017-10-25 03:46:41

标签: algorithm dynamic-programming coin-change

在考虑硬币变化时我想到了以下问题,但我不知道有效(伪多项式时间)算法来解决它。我想知道是否有任何伪多项式时间解决方案,或者是否有一些我遗漏的经典文献。

硬币更改问题有一个众所周知的pseudo-polynomial time dynamic programming解决方案,它会询问以下内容:

您拥有n个硬币,其ith的值为vi。存在多少个硬币子集,使得硬币值的总和为W

动态编程解决方案在O(nW)中运行,是经典的。但是我对以下几点概括感兴趣:

如果ith硬币的值不再是vi,而是可以假设一组l_ivi = {vi1, vi2, vi3, ..., vili},该怎么办?现在,问题是:存在多少个硬币子集,这样就存在硬币分配给值,使得这些硬币的值之和为W

(对于所有li = 1,经典的硬币更改问题实际上是i的问题的一个实例,所以我不期望多项式时间解决方案。)

例如,给定n = 3W = 10以及以下硬币:

  1. l1 = 4, v1 = {3, 6, 7, 10}
  2. l2 = 2, v2 = {1, 10}
  3. l3 = 2, v3 = {3, 4}
  4. 然后,有4个子集:

    1. 仅使用硬币1,将此硬币指定为值10
    2. 仅使用硬币2,将此硬币指定为值10
    3. 获取硬币13,将其分配为值73,分别为 分别为64 - 这些被认为是相同的方式。
    4. 获取硬币123,并将其分配为值613。< / LI>

      我遇到的问题恰恰是第三种情况;修改这个问题的经典动态编程解决方案很容易,但它会将这两个子集统一为不同,因为不同的值被分配,即使所用的硬币是相同的。

      到目前为止,我只能找到针对此问题的简单指数时间算法:考虑每个2^n子集,并运行标准动态编程硬币更改算法(O(nW^2) )检查这个硬币子集是否有效,给出O(2^n*n*W^2)时间算法。那不是我在这里寻找的;我正试图找到一个没有2^n因子的解决方案。

      你能为我提供一个伪多项式时间算法来解决这个问题,还是可以证明不存在,除非P = NP?也就是说,这个问题是NP完全的(或类似的)。

1 个答案:

答案 0 :(得分:0)

也许这很难,但你问这个问题的方式似乎并非如此。

  

取硬币1和3,分别分别为7和3或6和4 - 这些被认为是相同的。

让我们用这种方式编码两个等价的解决方案:

  1. ((1,3),(7,3))
  2. ((1,3),(6,4))
  3. 现在,当我们记住一个解决方案时,我们不能只问这对中的第一个元素(1,3)是否已经解决了?然后我们将抑制计算(6,4)解决方案。