以下是两个改变金钱问题的计划。第一个只是一个获得所有组合的递归程序,第二个是使用动态编程。但是,当我在第二个工作时,我遇到了麻烦。它应该比第一个更快,但我的程序运行FOREVER来做到这一点。我很确定我正在使用动态编程,但我不知道它的问题是什么?
注意:总计是要更改的资金,单位是具有不同值的列表,存储的是存储步骤值的字典。
首先:
def changeMoney(total, units):
if ( total == 0 ):
return [{}]
elif ( total < 0 ):
return []
else:
n = len(units)
ret = []
for i in range(0,n):
sols = changeMoney(total-units[i],units[i:n])
for sol in sols:
if ( units[i] in sol ):
sol[units[i]] += 1
else:
sol[units[i]] = 1
ret.append(sol)
return ret
print(dpChangeMoney(300,[100,50,20,10,5,2,1],{}))
第二
import copy
def dpChangeMoney(total, units, stored):
key = ".".join(map(str,[total] + units))
if key in stored:
return stored[key]
else:
if ( total == 0 ):
return [{}]
elif ( total < 0 ):
return []
else:
n = len(units)
for i in range(0,n):
sols = copy.deepcopy(dpChangeMoney(total-
units[i],units[i:n], stored))
for sol in sols:
if ( units[i] in sol ):
sol[units[i]] += 1
else:
sol[units[i]] = 1
if key in stored:
if sol not in stored[key]:
stored[key] += [sol]
else:
stored[key] = [sol]
return stored[key]
print(dpChangeMoney(300,[100,50,20,10,5,2,1],{}))
答案 0 :(得分:1)
这是一种更快捷的方法:
def dpChangeMoney(total, units, stored, min_ix=0):
if total < 0:
return []
if total == 0:
return [{}]
if min_ix == len(units):
return []
key = (total, min_ix)
if key in stored:
return stored[key]
sol_list = []
u = units[min_ix]
for c in range(total // u + 1):
sols = dpChangeMoney(total - c*u, units, stored, min_ix + 1)
for sol in sols:
if c > 0:
sol2 = sol.copy()
sol2[u] = c
else:
sol2 = sol
sol_list.append(sol2)
stored[key] = sol_list
return sol_list
如果按如下方式调用,它将打印指定大小写的解决方案数:
print(len(dpChangeMoney(300, [100,50,20,10,5,2,1], {})))
结果是:
466800
在我的系统上,这需要一秒钟才能运行。 (当然,您可以打印实际的解决方案,但有很多!)
要查看总共10
的实际解决方案:
print(dpChangeMoney(10, [100,50,20,10,5,2,1], {}))
结果是:
[{1: 10}, {1: 8, 2: 1}, {1: 6, 2: 2}, {1: 4, 2: 3}, {1: 2, 2: 4}, {2: 5}, {1: 5, 5: 1}, {1: 3, 2: 1, 5: 1}, {1: 1, 2: 2, 5: 1}, {5: 2}, {10: 1}]
答案 1 :(得分:0)
我只是弄清楚算法中的问题是什么。我将在截止日期之后更新更快的算法。感谢您的建议和指示。 ë