【问题标题】:Combining recursion with a loop to find maximal value将递归与循环相结合以找到最大值
【发布时间】:2018-12-18 14:28:05
【问题描述】:

我正在尝试解决递归练习并感到非常困惑。 问题如下:

假设我有一个 n 平方米的公寓, i = [1,2,3..., n] 是平方米的单位,[p1, p2, p3, ..., pn] 是对应的每平方米价格(例如 p1 是1平方米,pn是n平方米的价格)。

我想找到分配我的公寓的最佳方式,这会给我带来“最大的收入”。

示例 - 如果我有 4 平方米的公寓,并且尺寸 1、2、3、4 的价目表对应的是 [1、5、8、9],那么这些是选项集:

  • 将公寓作为一个 4 平方米的单位(价值:9)
  • 将4平方米分成1、1、1、1平方米(总值:4)
  • 将4平方米分成1、1、2平方米(总值:7)
  • 将4平方米分成2,2平方米(总值:10)
  • 将 4 平方米分成 1,3 平方米(总值:9)

因此我的函数“profit”应该为输入返回数字 10: 利润([1,5,8,9], 4)

我被要求使用以下模式解决这个问题,其中递归调用必须仅在循环内:

def profit(value, size):
    ...
    for i in range(size):
        ...
    return ...

在很长一段时间后,我设法在没有循环条件的情况下解决了这个问题,但这真的让我很沮丧,递归函数是多么困难和不直观。 对于此类问题,我真的很感激一般指导提示,或者即使您可以将我推荐给其他可能有助于我更好地学习该主题的资源。有时我很难跟上。

当然,感谢您对这个特定功能的帮助...

【问题讨论】:

    标签: python python-3.x loops recursion


    【解决方案1】:

    您可以创建一个函数来查找正方形大小范围的可能组合。然后,对于每个总和为四个的组合,可以找到最大地板尺寸:

    def profit(value, size):
      def combinations(d, _size, current = []):
        if sum(current) == _size:
          yield current
        else:
          for i in d:
            if sum(current+[i]) <= _size:
              yield from combinations(d, _size, current+[i])
      options = list(combinations(range(1, size+1), size))
      prices = dict(zip(range(1, size+1), value))
      result = max(options, key=lambda x:sum(prices[i] for i in x))
      return sum(prices[i] for i in result)
    
    print(profit([1,5,8,9], 4))
    

    输出:

    10
    

    【讨论】:

    • 这与原始问题的格式不同,我假设它是@Limitless 不允许更改的问题的模板,您的递归函数需要 3 个参数
    • @ChristianScillitoe 递归函数可以用另一个包含所需签名的函数包装。请查看我最近的编辑。
    • 恐怕@ChristianScillitoe 是对的,但谢谢!
    • @Ajax1234 在您的代码中的 Profit() 不是递归函数。它从不调用自己。 Limitless 要求递归解决方案。
    • @ChristianScillitoe 解决方案是递归的,然而,调用递归combinations函数的是profit
    【解决方案2】:

    我不想给你完整的答案,因为这似乎是一个任务。但是,我将尝试将您推向正确的方向,说明为什么递归在这里是最佳的。我在您的示例中添加了一行代码,我认为这会对您有所帮助。在将其添加到您的代码之前,我建议您尝试完全了解这里发生的事情。

    def profit(value, size):
        for i in range(size):
            # Get the profit of the size before this combined with a 1
            profit(value, size - 1) + profit(value, 1)
    

    如果您无法理解为什么这很有用,请随时发表评论,稍后我可以为您提供更深入的解释。

    编辑:

    实现递归函数时要牢记的一个关键概念是您的基本情况。

    在此示例中,您已经知道每种尺寸的值是多少,因此请将其纳入您的解决方案中。

    def profit(value, size):
        # BASE CASE
        if size == 1 :
            return value[0]
    
        # Size > 1
        for i in range(size):
            # Return the maximum value of all given combinations.
            return max(value[size], profit(value, size - 1) + profit(value, 1))
    

    现在这是一个几乎完整的解决方案,只是缺少一个部分。

    提示:此代码目前无法测试利润(值,2)+利润(值,2)(恰好是这种情况下的最大利润)

    【讨论】:

    • 我可以看到:for i in range(size): profit(value, size-(i+1)) 帮助我遍历所有组合,但我仍然遇到问题对递归中的值求和,我不知道如何处理这个..
    【解决方案3】:

    使用以下函数解决:

    def profit(value,size):
        if size <= 0:
            return 0
        lst1 = []
        for i in range(size):
            lst1.append(profit(value, size-(i+1))+value[i])
        return max(lst1)
    

    【讨论】:

    • 不错!看起来比 Ajax 建议的要干净得多
    猜你喜欢
    • 1970-01-01
    • 2018-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-20
    • 2011-02-09
    相关资源
    最近更新 更多