【发布时间】:2012-11-29 23:46:01
【问题描述】:
我正在尝试解决Project Euler problem 240:
20 个 12 面骰子(面数为 1 到 12)有多少种方法可以掷出,使前十名的总和为 70?
我想出了解决这个问题的代码。但是计算起来确实需要很多时间。我知道这种方法很糟糕。有人可以建议我如何修复此代码以更好地执行吗?
import itertools
def check(a,b): # check all the elements in a list a, are lesser than or equal to value b
chk=0
for x in a:
if x<=b:
chk=1
return chk
lst=[]
count=0
for x in itertools.product(range(1,13),repeat=20):
a=sorted([x[y] for y in range(20)])
if sum(a[-10:])==70 and check(a[:10],min(a[-10:])):
count+=1
下面的代码是针对problem的描述中定义的问题。它完美地工作并给出了确切的解决方案....
import itertools
def check(a,b):
chk=1
for x in a:
if x>b:
chk=0
break
return chk
count=0
for x in itertools.product(range(1,7),repeat=5):
a=sorted([x[y] for y in range(5)])
if sum(a[-3:])==15 and check(a[:2],min(a[-3:])):
count+=1
【问题讨论】:
-
你应该重新思考这个问题。你有 20 个插槽,你需要用 1-12 的数字填充它们,这样 10 个数字最大的插槽加起来就是 70。我们已经可以减少这个了,你有 10 个插槽,1-12 = 70。然后对于每个解决方案,您还有 10 个插槽,可以安排它们的值都不大于解决方案插槽中的任何值。请记住,问题是有多少种方法可以做到这一点 - 所以每个解决方案 10 都有许多其他可以以多种不同方式排列的插槽。
-
Inbar,.. 最初我为类似谜题测试了这段代码,其中要求 5 个骰子,前三名的总和应该是 15,这样的组合有多少?这段代码立即给出了正确的 1111 解决方案。现在复杂性已增加到 20 个骰子和 12 个面.. 这需要很多时间.. 我需要一种替代方法或方法,它可以在没有蛮力的情况下解决。
标签: python puzzle itertools dice