我试图在CodeChef上解决这个问题:http://www.codechef.com/problems/COINS
但是当我提交我的代码时,它显然需要很长时间来执行,并且说时间已经过期。我不确定我的代码是低效的(我觉得不是这样),还是I/O有问题。有9秒的时间限制,可以解决最多10个输入,0<;=n<;=1 000 000 000。在
In Byteland they have a very strange monetary system.
Each Bytelandian gold coin has an integer number written on it. A coin n can be exchanged in a bank into three coins:
n/2
,n/3
andn/4
. But these numbers are all rounded down (the banks have to make a profit).You can also sell Bytelandian coins for American dollars. The exchange rate is 1:1. But you can not buy Bytelandian coins.
You have one gold coin. What is the maximum amount of American dollars you can get for it?
这是我的代码:输入1000000000似乎花费了太长的时间
def coinProfit(n):
a = n/2
b = n/3
c = n/4
if a+b+c > n:
nextProfit = coinProfit(a)+coinProfit(b)+coinProfit(c)
if nextProfit > a+b+c:
return nextProfit
else:
return a+b+c
return n
while True:
try:
n = input()
print(coinProfit(n))
except Exception:
break
我只是试着注意到一些事情。。。这不必被认为是答案。在
在我最近的机器上,用
n = 100 000 000
计算要花30秒。我想对于您刚刚编写的算法来说,这是很正常的,因为它一次又一次地计算相同的值(您没有像其他答案中建议的那样使用缓存优化递归调用)。在此外,问题的定义相当温和,因为它坚持认为:每一枚拜特兰金币上都有一个整数,但这些数字都被四舍五入。了解了这一点,您应该将函数的前三行转换为:
这将防止
a, b, c
变成float
数字(至少是Python3),这会让你的计算机陷入一个巨大的递归混乱,即使最小的值是n
。在您可以通过将结果存储在某种类型的
cache
中来优化程序。因此,如果结果存在于cache
中,则无需执行计算,否则计算并将值放入cache
。这样可以避免计算已计算的值。E、 g问题是您的代码将每个递归调用分支为三个新调用。这会导致指数行为。在
不过,好的一点是,大多数调用都是重复的:如果用
40
调用coinProfit
,这将级联到:您看到的是大量的工作被重复(在这个小例子中,
coinProfit
已经在10
上调用了两次)。在您可以使用动态编程来解决这个问题:存储以前的计算结果,防止您在这部分上再次分支。在
可以自己实现动态编程,但可以使用
@memoize
修饰符自动执行此操作。在现在这个函数做了很多工作。在
^{pr2}$@memoize
对函数进行转换,以便:对于函数,保留已计算输出的数组。如果对于一个给定的输入,输出已经被计算出来,它将被存储在数组中,并立即返回。否则,它将按照您的方法定义进行计算,存储在数组中(供以后使用)并返回。在正如@steveha指出的,python已经有一个内置的
memoize
函数,称为lru_cache
,更多信息可以在here中找到。在相关问题 更多 >
编程相关推荐