<p>对于这种解决方案,关键的见解是,每一笔金额都可以表示为一套参考硬币或一套参考硬币加上一定数量的填充硬币。例如,如果金额为42,则可以表示为28+7+7或27+5+5+5</p>
<p>注:参考金额需要是从24开始到30的连续整数,以允许填充硬币的值为7。这是一个棘手的部分</p>
<p>解决方案:</p>
<pre><code>def coin_count(amount, filler_coin_value=5):
reference = {
24: (7, 7, 5, 5),
25: (5, 5, 5, 5, 5),
26: (7, 7, 7, 5),
27: (5, 5, 5, 5, 7),
28: (7, 7, 7, 7),
29: (7, 7, 5, 5, 5),
30: (5, 5, 5, 5, 5, 5)
}
coins = []
while not amount in reference:
amount -= filler_coin_value
coins.append(filler_coin_value)
coins.extend(reference[amount])
return coins
</code></pre>
<p>虽然上述解决方案可行,但可以通过用一些(公认的棘手的)数学替换<code>while</code>循环来优化它</p>
<pre><code>def coin_count_optimized(amount, filler_coin_value=5):
reference = {
24: (7, 7, 5, 5),
25: (5, 5, 5, 5, 5),
26: (7, 7, 7, 5),
27: (5, 5, 5, 5, 7),
28: (7, 7, 7, 7),
29: (7, 7, 5, 5, 5),
30: (5, 5, 5, 5, 5, 5)
}
filler_count, off_by = divmod((amount - 24), filler_coin_value)
coins = [filler_coin_value] * filler_count
coins.extend(reference[24 + off_by])
return coins
</code></pre>
<p>两种方法的时间比较:</p>
<pre><code>import time
start_time = time.time()
for amount in range(24, 1000):
coin_count(amount)
print("coin_count", time.time() - start_time)
start_time = time.time()
for amount in range(24, 1000):
coin_count_optimized(amount)
print("coin_count_optimized", time.time() - start_time)
</code></pre>
<p>输出:</p>
<pre><code>coin_count 0.022232770919799805
coin_count_optimized 0.0019953250885009766
</code></pre>