【问题标题】:Different ways to sum a number using numbers less than or equal to k使用小于或等于 k ​​的数字对数字求和的不同方法
【发布时间】:2019-12-23 19:35:23
【问题描述】:

例子:给定total = 8和k = 2,将8表示为1和2之间的整数之和的不同方式的数量是5种方式:

[1, 1, 1, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 1, 2]
[1, 1, 1, 1, 2, 2]
[1, 1, 2, 2, 2]
[2, 2, 2, 2]

约束:

1 <= total <= 1000
i <= k <= 100

我们如何解决这个问题?动态规划?

【问题讨论】:

  • 到目前为止你尝试了什么?
  • 此外,您能否提供更多详细信息,例如最大值?
  • @Damien 我添加了详细信息。
  • @Yonlif 我知道有一个非常相似的问题 - geeksforgeeks.org/… 但我仍然无法解决它。
  • 在 30 分钟的技术面试中遇到了这个问题,疯了

标签: algorithm dynamic-programming


【解决方案1】:

在面试中,如果你怀疑问题可能是动态编程,你应该立即将其写成递归函数,然后添加缓存(也称为 memoizing)。

那么我们的基本情况是什么?

  1. total 为 0。在这种情况下,一个空的和就可以了。

  2. total

  3. 我们正在考虑的数字范围是空的。这种情况下就没有办法了。

在其他情况下,我们要么减小列表的大小,要么使用列表中最大的数量。

这种递归解决方案非常简单。

def ways_to_sum(total, lower, upper):
    if total < 0:
        return 0
    elif total == 0:
        return 1
    elif upper < lower:
        return 0
    else:
        return ways_to_sum(total - upper, lower, upper) + ways_to_sum(total, lower, upper - 1)

print(ways_to_sum(8, 1, 2)) # prints 5
print(ways_to_sum(800, 1, 5)) # locks up

现在的问题是我们一遍又一遍地做很多工作。因此我们添加缓存:

cached_ways_to_sum = {}
def ways_to_sum(total, lower, upper):
    if total < 0:
        return 0
    elif total == 0:
        return 1
    elif upper < lower:
        return 0
    else:
        key = (total, lower, upper)
        if key not in cached_ways_to_sum:
            cached_ways_to_sum[key] = ways_to_sum(total - upper, lower, upper) + \
                                      ways_to_sum(total, lower, upper - 1)
        return cached_ways_to_sum[key]

print(ways_to_sum(8, 1, 2)) # prints 5
print(ways_to_sum(800, 1, 5)) # prints 147624812

如果此时您被要求另一种方法来做,那么您才应该考虑采用自下而上的 DP 解决方案。即便如此,我也会考虑缓存中的内容并从中构建它。

【讨论】:

  • 请增加时间和内存复杂度:)
猜你喜欢
  • 1970-01-01
  • 2017-03-16
  • 2018-02-15
  • 2021-09-21
  • 2019-09-26
  • 1970-01-01
  • 1970-01-01
  • 2017-06-16
  • 2019-09-25
相关资源
最近更新 更多