在一般情况下,硬币值可以是任意的,您提出的问题称为背包问题,并且已知属于 NP-complete ( Pearson, D. 2004 ),因此无法在多项式时间内解决,例如动态规划。
以 x[2] = 51, x[1] = 50, x[0] = 1, X = 100 的病态例子为例。那么需要算法“考虑”用硬币 x[2 找零的可能性],或者从 x[1] 开始进行更改。用于国家造币的第一步,也称为贪心算法——也就是说,“使用小于工作总量的最大硬币”将不适用于病态造币。相反,这样的算法经历了组合爆炸,使它们符合 NP-complete 的条件。
对于某些特殊的硬币价值安排,例如实际上所有实际使用的,包括虚拟系统 X[i+1] == 2 * X[i],有非常快的算法,甚至在虚拟系统中 O(1)给定的情况,以确定最佳输出。这些算法利用硬币价值的属性。
我不知道动态编程解决方案:一种利用编程主题所需的最佳子解决方案的解决方案。一般来说,一个问题只能通过动态规划来解决,如果它可以分解为子问题,当优化解决时,可以重新组合成一个可证明是最优的解决方案。也就是说,如果程序员不能在数学上证明(“证明”)重新组合问题的最优子解会产生最优解,则不能应用动态规划。
动态规划的一个常见示例是多个矩阵相乘的应用。根据矩阵的大小,选择将A · B · C评估为两种等价形式中的一种:(( A · B )· C ) 或 ( A ·( B · C )) 会导致不同的计算乘法和加法的数量。也就是说,一种方法比另一种方法更优化(更快)。动态规划是将不同方法的计算成本制成表格的主题,并根据动态计算的时间表(或程序)执行实际计算在运行时。
一个关键特性是计算是根据计算出的调度执行的,而不是通过枚举所有可能的组合——无论枚举是递归执行还是迭代执行。在矩阵相乘的例子中,在每一步,只选择成本最低的乘法。因此,永远不会计算中间成本次优计划的可能成本。换句话说,调度不是通过搜索所有可能的调度以获得最优调度来计算的,而是通过从无到有逐步构建最优调度来计算的。
命名法“动态规划”可以与“线性规划”相比较,其中“程序”也用于“调度”的含义。
要了解有关动态编程的更多信息,请参阅我所知道的关于算法的最伟大的书籍,Cormen、Leiserson、Rivest 和 Stein 的“算法简介”。 “Rivest”是“RSA”的“R”,而动态规划只是乐谱的一章。