0

我试图解决这个问题:硬币找零优化

假设我有一组N个硬币{A_1,A2,...,A_N}。总是会出现一个值为 1的硬币。 I 需要达到M的最小数量的硬币是多少?

约束条件是:

  • 1≤N≤25
  • 1≤米≤10^6
  • 1≤A_I≤100

好的,我知道这是改变的问题。 我试图解决这个问题,使用广度优先搜索,动态编程和贪婪(这是不正确的,因为它并不总是提供最佳的解决方案)。但是,我得到超时限制(3秒)。

所以我想知道是否有这个问题的优化。 描述和约束称为我的注意,但我不知道如何使用它对我有利:

  • 总是会出现值为1的硬币。
  • 1≤A_I≤100

我在维基百科看到,这个问题也可以通过“与概率卷积树动态规划”来解决。但我什么都听不懂。

你能帮我吗? 这个问题可以在这里找到:http://goo.gl/nzQJem

回答

0

a_n是最大的硬币。使用这两个线索:

  • 结果是>= ceil(M/a_n)
  • 结果的配置有很多a_n's

最好是尝试用最大的a_n's比检查它是否是用更少的a_n's更好的结果,直到它有可能找到更好的结果。

类似于:let R({a_1, ..., a_n}, M)是返回给定问题结果的函数。比R可以执行:

num_a_n = floor(M/a_n) 
best_r = num_a_n + R({a_1, ..., a_(n-1)}, M-a_n*num_a_n) 
while num_a_n > 0: 
    num_a_n = num_a_n - 1 
    # Check is it possible at all to get better result 
    if num_a_n + ceil(M-a_n*num_a_n/a_(n-1)) >= best_r: 
    return best_r 
    next_r = num_a_n + R({a_1, ..., a_(n-1)}, M-a_n*num_a_n) 
    if next_r < best_r: 
    best_r = next_r 
return best_r 
+0

谢谢你的回答。我试图实现这一点,在某些情况下速度很快,但在其他情况下速度很慢。然后我尝试了记忆,但它变成了O(n * m)。 – skide 2014-09-19 02:14:20

+0

我认为它可以在O(n * min(M,a_n * a_ {n-1}))中完成记忆。不需要在M-a_n * a_ {n-1}下面搜索。 – Ante 2014-09-19 07:19:56

+0

非常聪明的解决方案!现在我得到了AC。非常感谢你! – skide 2014-09-20 14:40:46