递归记忆方法邮票问题

发布于 2025-01-20 22:50:38 字数 922 浏览 3 评论 0原文

上下文: 我们提供各种面额的邮票,如 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夏有森光若流苏 2025-01-27 22:50:38

首先,您的逻辑是错误的。

我的猜测是,您获得无限递归的原因是因为

exc = min_stamps(x, den[:-1])

您的代码永远不会通过此行。第一个执行,den =(1,5,66,85,100),之后den =(1,5,66,85),之后=(1,5,66,85) ....直到其空正确?但是,即使是空的,den [-1]仍然是(),因此是无限的递归。
另外,我认为您的整个代码完全是错误的,我认为我真的不理解。

其次,没有终止递归的基本案例。

这就是我写

def f(x, den) :
 global mem
 # memoization
 if x in mem: return mem[x]
 # base case, when the value is one of the stamps, there's exactly one way to make it
 elif x in den: return 1
 # prevents negative values from being counted
 elif x<0: return float("inf")
 # the main logic
 else:
  mem[x] = float("inf")
  for stamp on den:
   mem[x] = min(mem[x], f(x-stamp, den) +1) 
  return mem[x]

这件代码的方式,因为最小数量的方法将涉及从数字中的任何邮票的值进行亚键值。我们添加1个原因是使用一张邮票的价值。递归进行此操作并进行回忆,您有标准的动态编程问题

First of all, your logic is wrong.

My guess is, the reason you're getting infinite recursion is because of this

exc = min_stamps(x, den[:-1])

Your code will never pass this line. The first execution, den=(1,5,66,85,100), after that den=(1,5,66,85), after that den=(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

def f(x, den) :
 global mem
 # memoization
 if x in mem: return mem[x]
 # base case, when the value is one of the stamps, there's exactly one way to make it
 elif x in den: return 1
 # prevents negative values from being counted
 elif x<0: return float("inf")
 # the main logic
 else:
  mem[x] = float("inf")
  for stamp on den:
   mem[x] = min(mem[x], f(x-stamp, den) +1) 
  return mem[x]

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文