【问题标题】:Determine if you can make change with N denominations using each denomination only once and with at most k coins确定你是否可以用 N 个面额的硬币进行零钱,每个面额只用一次,最多用 k 个硬币
【发布时间】:2016-04-25 12:38:39
【问题描述】:

这是硬币兑换问题的一个版本。因此,这是一个动态规划问题。

我知道如何确定您是否可以进行零钱,如果您可以使用每种面额的最多一枚硬币,或者您最多可以使用 k 枚硬币,但不能同时使用这两种硬币。

【问题讨论】:

  • 是的。我知道这个。我不知道如何将 k 个硬币的约束计算到循环中。
  • @user2357112 “我知道如何确定您是否可以进行零钱,如果您可以使用每种面额的最多一枚硬币,或者您最多可以使用 k 枚硬币,但不能同时使用这两种硬币。” ...将其解释为我知道这是 0-1 背包问题的变体,但是我不知道如何结合 all 约束。相关地,请看​​问题 3:cise.ufl.edu/class/cot5405sp10/exams/Midterm3sol.pdf。根据您的限制,您可以获得非常不同的复发。我的问题是你如何结合所有的限制。

标签: algorithm dynamic-programming knapsack-problem coin-change


【解决方案1】:

会不会和 N 个面额一样,但要再加一个最终检查以确保 N

changeWithN(amt, k){ ... 返回 n

【讨论】:

  • 一种思考方式是:如何实施检查?你能把支票作为重复的一部分吗?我不知道 changeWithN(amt, k){ ... return n
  • 你能给我一些 suedo 代码或其他解决方案的东西吗?到时候我可能会提供更好的帮助。你说你可以求解 n 或求解 k,给我看看,这样我就可以看到你在做什么,也许还能看到如何组合。
  • 也许这会有所帮助:cise.ufl.edu/class/cot5405sp10/exams/Midterm3sol.pdf 看看第三季度的 a、c 部分。
【解决方案2】:

组合约束相当简单。我们可以构建一个三维表,其维度表示允许的最大硬币、允许的硬币数量和目标总和,或者我们可以说“搞砸了”,然后在简单的递归解决方案之上进行记忆。在 Python 中:

# Assume we have a memoization decorator.
# functools.lru_cache(maxsize=None) would do.
@memoize
def knapsack_possible(coin_tuple, target, k):
    if not target:
        # Target achieved.
        return True
    elif not coin_tuple or not k:
        # Out of coins.
        return False
    else:
        return (knapsack_possible(coin_tuple[:-1], target, k) or
                knapsack_possible(coin_tuple[:-1], target-coin_list[-1], k-1)

【讨论】:

  • 我认为我们可以改进的可能是,计算更改目标所需的最小硬币数量。可以这样完成 f( n , target ) = min(f(n-1,target) , f(n-1,target - coin[n]) + 1 ) .. 现在如果我们可以用
  • @ShubhamSharma:不过,这并不能让我们跟踪我们使用了哪些硬币。
  • 我们可以随时回溯生成集合而不影响复杂度
  • @ShubhamSharma:哦,我明白了。您正在计算前 n 个硬币的最小数量(或 n+1 取决于索引约定),我们需要达到等于目标的总和。我以为你忽略了对重复使用硬币的限制。尽管我认为记忆化版本与您的建议的记忆化版本基本上相同的调用树,但您的重现确实优于我提出的 3D 表格。
猜你喜欢
  • 1970-01-01
  • 2020-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多