我正试图解决这个问题:
假设我有一组n个硬币{a_1,a2,...,a_n}。有价值的硬币 始终会出现1。我最小的硬币数是多少 需要达到M?
约束是:
- 1≤n≤25
- 1≤m≤10^ 6
- 1≤a_i≤100
好的,我知道这是变革问题。 我试图使用广度优先搜索,动态编程和贪婪来解决这个问题(这是不正确的,因为它并不总是提供最佳解决方案)。但是,我的时间限制超过了(3秒)。
所以我想知道这个问题是否有优化。 描述和约束引起了我的注意,但我不知道如何使用它对我有利:
我在维基百科上看到,这个问题也可以通过“使用概率卷积树进行动态编程”来解决。但我什么都听不懂。
你能帮帮我吗? 这个问题可以在这里找到:http://goo.gl/nzQJem答案 0 :(得分:1)
让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