试试这个:
def memoize(fcn, cache = {}):
def decorated(d, p):
if p not in cache:
cache[p] = fcn(d, p)
return cache[p]
return decorated
@memoize
def mc(d, p):
if p in d:
return (1, [p])
cands = [n for n in d if n < p]
if not cands:
return (10**20, [])
d_i, pair = min(
[(d_i, mc(d, p-d_i)) for d_i in cands],
key=lambda e: e[1][0]
)
return (1 + pair[0], pair[1] + [d_i])
在您的示例中,它将返回一对 (3, [21, 21, 21])。
这是一个快速的解决方案。如果您需要集成或分发它,我建议您使用 OOP 样式,如下所示:
class MinimumCoinChangeSolver(object):
def __init__(self):
self.coins = None
self.count = None
self.__cache = {}
def solve(self, coins, amount):
self.reset_cache()
self.coins = self.__recursive_solve(coins, amount)
self.count = len(self.coins)
def reset_cache(self):
self.__cache = {}
def __recursive_solve(self, coins, amount):
# try to find solution in cache
if amount in self.__cache:
solution = self.__cache[amount]
else:
# if given amount equals to one of teh coins, return list which contains corresponding coin (it equals to amount)
if amount in coins:
solution = [amount]
else:
# find coins candidates, they are less then given amount
coins_cands = filter(
lambda coin: coin < amount,
coins
)
# if there is no coins candidate, return no coins (it is an empty list on coins)
if not coins_cands:
solution = []
else:
# try to use every coin among the candidates, and recursively find list of coins in every case
solutions = map(
lambda coin: self.__recursive_solve(coins, amount - coin),
coins_cands
)
# ignoring empty solutions
solutions = filter(
lambda sol: bool(sol),
solutions
)
# if there is no non-empty solutons, return empty list
if not solutions:
solution = []
else:
# choose the solution which has minimum number of coins
min_solution = min(
solutions,
key=lambda sol: len(sol)
)
# remember corresponding coin
coin = amount - sum(min_solution)
# solution
solution = min_solution + [coin]
# save solution in cache
self.__cache[amount] = solution
# return
return solution
if __name__ == "__main__":
solver = MinimumCoinChangeSolver()
solver.solve([1, 5, 10, 25, 21], 63)
print solver.coins
print solver.count