【发布时间】:2016-07-04 23:28:12
【问题描述】:
我试图解决硬币兑换问题。因为我住在欧洲,所以让我们把它变成一个欧元问题。 我们需要 5 欧元。 我们可以使用 10、20、50 美分、1 欧元、2 欧元和 5 欧元。 5欧有多少种可能?
cents = 50
denominations = [50, 20, 10, 5, 2, 1]
names = {50: "", 20: "", 10 : "", 5 : "", 2 : "", 1: ""}
def count_combs(left, i, comb, add):
if add: comb.append(add)
if left == 0 or (i+1) == len(denominations):
if (i+1) == len(denominations) and left > 0:
comb.append( (left, denominations[i]) )
i += 1
while i < len(denominations):
comb.append( (0, denominations[i]) )
i += 1
print " ".join("%d %s" % (n,names[c]) for (n,c) in comb)
return 1
cur = denominations[i]
return sum(count_combs(left-x*cur, i+1, comb[:], (x,cur)) for x in range(0, int(left/cur)+1))
print count_combs(cents, 0, [], None)
效果很好,但是因为这段代码对我来说非常困难(这个递归在这里只能在魔术的帮助下工作)我使用了另一个代码,这对我来说很容易理解。
def money(goal, money_avail, money_used):
if sum(money_used) == goal:
yield money_used
elif sum(money_used) > goal:
pass
elif money_avail == []:
pass
else:
for change in money(goal,money_avail[:], money_used+[money_avail[0]]):
yield change
for change in money(goal,money_avail[1:], money_used):
yield change
results = []
for s in money(50, [1,2,5,10,20,50], []):
results.append(s)
cn = 0
for i in results:
cn+=1
i = str(i)
print cn, i
print len(results)
他们都给了我相同长度的答案 - 有 451 种可能性。
def is_5euro(L):
return sum(L) == 5.0
moneybag = []
for c10 in range(51):
for c20 in range(26):
for c50 in range(11):
for e1 in range(6):
for e2 in range(3):
for e5 in range(2):
denom = [c10 * 0.1, c20 * 0.2, c50 * 0.5, e1 * 1, e2 * 2, e5 * 5]
if is_5euro(denom):
moneybag.append([c10, c20, c50, e1, e2, e5])
print len(moneybag)
但是这个解决方案只给了我们 446 种可能性。
所以我检查了列表结果和第三种(for for for for)算法之间的区别,似乎没有考虑以下情况:
>>>
[[0, 0, 0, 0, 1, 48], [0, 0, 0, 0, 2, 46], [0, 0, 0, 0, 23, 4], [0, 0, 0, 0, 24, 2], [0, 0, 0, 1, 2, 41]]
(48 x 10) + (1 x 20) 美分
(46 x 10) + (2 x 20) 美分
(4 x 10) + (23 x 20) 美分
(2 x 10) + (24 x 20) 美分
(41 x 10) + (2 x 20) + (1 x 50) 美分
这似乎很荒谬。你知道为什么它不像第一个和第二个算法那样工作吗?
【问题讨论】:
-
您是否尝试打印出
is_5euro(L)针对这些情况返回的内容? This question 和其他链接的最有可能相关。 -
@Lafexlos 不是真的,只有答案列表。这就是我创建缺失元素列表的方式。如果算法适用于上述任何一项,则结果将为 50。例如 sum[0,0,0,0,1x2,48x1]。
-
您可以尝试添加每个子集,如果加起来达到 5 欧元,则将可能性增加 1?
标签: python algorithm debugging math permutation