代码之家  ›  专栏  ›  技术社区  ›  Abhijit Sarkar

硬币兑换问题变化背后的想法是什么?

  •  0
  • Abhijit Sarkar  · 技术社区  · 7 年前

    问题:给定一组 n 面值独特的硬币 change ,查找更改的方法 改变 .

    假设我们可以多次使用一个名称,这是我想出的伪代码

    1. NUM-WAYS(denom[], n, change)
    2.   dp = [change + 1][n + 1]
    3.   for i = 0 to n
    4      dp[i][0] = 1
    5.   xs = denom.sorted
    
    6.   for i = 1 to change
    7.     for j = 1 to n
    8.       if xs[j - 1] > i
    9.         dp[i][j] = dp[i][j - 1]
    10.      else
    11.        dp[i][j] = dp[i - xs[j - 1]][j] + dp[i][j - 1]
    
    12.  return dp[change][n]
    

    上面的算法我很清楚。但是,如果我们只允许使用一次面额,那么第11行将改为 dp[i - xs[j - 1]][j - 1] + dp[i][j - 1] 好像我们根本不允许使用当前的面额。我没能把我的头绕过去。你能解释一下吗?

    以下是一些测试运行:

    Change: 3, denominations: [8, 3, 1, 2]
    11111
    01111
    01222
    01233
    
    // use once
    Change: 3, denominations: [8, 3, 1, 2]
    11111
    01111
    00111
    00122
    
    Change: 4, denominations: [3, 1, 2]
    1111
    0111
    0122
    0123
    0134
    
    // use once
    Change: 4, denominations: [3, 1, 2]
    1111
    0111
    0011
    0012
    0001
    
    1 回复  |  直到 7 年前
        1
  •  0
  •   Abhijit Sarkar    7 年前

    让 dp[i][j] 将解表示为 [i, j] -子问题;也就是说, dp[i] 是更改金额的方法数 i 使用硬币 j 通过 n .

    重复换币问题

    • 第一个案例假设 J -这个教派被拿走了。既然面额没有限制, J 可以保持不变,以便再次用于较小的子问题: dp[i - xs[j - 1]][j] .

    无重复的硬币兑换问题

    这和上面的问题一样,还有一个附加的限制条件,即某个面额的硬币只能取一次。

    • 第一个案例假设 J -这个教派被拿走了。因为我们不能用面额 J 不再, J 改变到 j-1 : dp[i - xs[j - 1]][j - 1]

    第二种情况在两个问题中是相同的,其中 J -忽略了面额。