递归记忆方法邮票问题
上下文: 我们提供各种面额的邮票,如 1、5、66、85、100。 假设我们有无限数量的每种面额的邮票,并且我们希望使用尽可能少的邮票数量达到某个值,例如 138。 一方面,我们可以有
138 = 100+5+5+5+5+5+5+5+1+1+1 (11 个邮票),
但最好使用
138 = 66+66+5+1 ( 4枚邮票)。
问题是创建一个函数 min_stamps(x,den)
来返回金额 x
所需的最小邮票数量,其中 den
是可用邮票面额的元组。我们假设所有金额都是正整数,并且 den
包含 1
,这保证了每个金额都是可能的。
我们被要求对这个问题使用递归记忆方法。我的尝试如下。
def min_stamps(x,den):
global MEMO
if (x,den) not in MEMO:
exc = min_stamps(x, den[:-1])
if den[-1] > x:
MEMO[(x,den)] = exc
else:
inc = min_stamps(x-den[-1], den[:-1])
MEMO[(x,den)] = min(inc,exc)
return MEMO[(x,den)]
当在 min_stamps(138,(1,5,66,85,100))
上使用上面的函数时,我得到 RecursionError: Maximum recursion Depletished
。我希望从这个价值面额对中得到 4,但我不确定如何解决这个问题,并且我不确定上面代码中解决问题的逻辑是否完全正确。
Context:
We have stamps available in various denominations like 1,5,66,85,100.
Suppose that we have an unlimited number of stamps of each denomination available, and we want to make a certain value, say 138, with the minimum possible number of stamps.
On the one hand we could have
138 = 100+5+5+5+5+5+5+5+1+1+1 (11 stamps),
but it's best to use
138 = 66+66+5+1 (4 stamps).
The question is to make a function min_stamps(x,den)
that returns the minimum number of stamps needed to make the amount x
, where den
is a tuple of the available denominations of stamps. We assume that all amounts are postive integers, and that den
includes 1
, which guarantees that it is possible to make every amount.
We have been asked to use a recursion memorisation approach on the question. My attempt is below.
def min_stamps(x,den):
global MEMO
if (x,den) not in MEMO:
exc = min_stamps(x, den[:-1])
if den[-1] > x:
MEMO[(x,den)] = exc
else:
inc = min_stamps(x-den[-1], den[:-1])
MEMO[(x,den)] = min(inc,exc)
return MEMO[(x,den)]
When using the function above on min_stamps(138,(1,5,66,85,100))
I get RecursionError: maximum recursion depth exceeded
. I expect to get 4 from this value-denomination pair, but I'm not sure how to fix this and I'm not sure if my logic in the code above for tackling the question is entirely correct.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,您的逻辑是错误的。
我的猜测是,您获得无限递归的原因是因为
您的代码永远不会通过此行。第一个执行,
den =(1,5,66,85,100)
,之后den =(1,5,66,85)
,之后=(1,5,66,85)....
直到其空正确?但是,即使是空的,den [-1]
仍然是()
,因此是无限的递归。另外,我认为您的整个代码完全是错误的,我认为我真的不理解。
其次,没有终止递归的基本案例。
这就是我写
这件代码的方式,因为最小数量的方法将涉及从数字中的任何邮票的值进行亚键值。我们添加1个原因是使用一张邮票的价值。递归进行此操作并进行回忆,您有标准的动态编程问题
First of all, your logic is wrong.
My guess is, the reason you're getting infinite recursion is because of this
Your code will never pass this line. The first execution,
den=(1,5,66,85,100)
, after thatden=(1,5,66,85)
, after thatden=(1,5,66,85)
....
till its empty right? But even when it's empty,den[-1]
will still be()
, hence infinite recursion.Also I think your whole code is just plain wrong, I don't think I really understand it.
Secondly, there's no base case to terminate the recursion.
Here's how I would've written the code
This works because, the minimum number of ways would involve subtrscting the value of any of the stamps from the number. We add 1 cause that's value for using one stamp. Do this recursively and memoize, you have your standard dynamic programming problem