无界背包/硬币更换与非标准硬币的最佳解决方案

时间:2015-06-16 07:50:43

标签: dynamic dynamic-programming knapsack-problem coin-change

我有以下问题:

  

给定目标大小N和一些随机的面额   生成的硬币存储在数组面额[]检查使用动态   编程,如果有一个最佳解决方案,将填补整个   使用最少量硬币的目标。

这是硬币兑换问题的一个典型例子,但与真实货币不同的是,每个面额都经过精心挑选,以便任何目标都可以匹配,情况并非如此。

我熟悉硬币更改问题中使用的算法以及如何构建动态编程数组以找到解决方案,但我如何首先检查是否存在解决方案?

1 个答案:

答案 0 :(得分:1)

让状态由DP[i][sum]表示:用于使用数组面额的起始i币来形成总和的最小硬币数。 然后复发可以表示为:

DP[i][sum]= min(DP[i-1][sum],DP[i][sum-denominations[i]]+1)

为什么? 第一个DP[i-1][sum]表示仅使用i-1硬币形成金额所需的硬币数量(我们排除第i个硬币的情况),另一种情况是我们包含第i个硬币(注意:我有假设我们可以多次包括硬币,这就是我写DP[i][sum-denominations[i]].

的原因

现在,基本情况DP[i][0]=0即NULL集(对于所有i属于0到n(面额数)!和DP[0][i]=+INFINITY其中1 <= i <= sum。< / p>

现在当DP表填满时,你可以很容易地检查DP [n(大小)] [sum]是否不等于+ INFINITY然后存在一个解决方案,否则不是..

如果您知道如何构建解决方案(如您所说),您也可以为此解决方案构建解决方案..

P.S。 :为了仅允许单次包含硬币面额,重复发生变为

DP[i][sum]= min(DP[i-1][sum],DP[i-1][sum-denominations[i]]+1)

用同样的逻辑!我认为基本情况会一样!