【发布时间】:2018-05-06 11:48:26
【问题描述】:
我正在练习动态编程。我专注于硬币交换问题的以下变体:
设S = [1, 2, 6, 12, 24, 48, 60] 是一组恒定的整数硬币面额。让n 是通过S 中的硬币可获得的正整数金额。考虑两个人A 和B。我可以通过多少种不同的方式将n 分配给A 和B 的人,以便每个人获得相同数量的硬币(忽略每个人实际获得的金额)?
示例
n = 6每人可以分成4种不同的方式:
-
A获得 {2, 2},B获得 {1, 1}。 -
A人员获得 {2, 1},B人员获得 {2, 1}。 -
A获得 {1, 1},B获得 {2, 2}。 -
A人员获得 {1, 1, 1},B人员获得 {1, 1, 1}。
请注意,每种方式对每个人来说都是非冗余的,即我们不会将 {2, 1} 和 {1, 2} 视为两种不同的方式。
以往的研究
我研究过非常相似的 DP 问题,例如硬币交换问题和分区问题。事实上,本站有问题指的几乎是同一个问题:
- Dynamic Programming for a variant of the coin exchange - 在这里,OP 研究递归关系,但引入奇偶约束似乎很困惑。
- Coin Change :Dynamic Programming - 在这里,OP 似乎在追求解决方案的重构。
- Coin change(Dynamic programming) - 在这里,OP 似乎也在追求解决方案的重构。
- https://cs.stackexchange.com/questions/87230/dynamic-programming-for-a-variant-of-the-coin-exchange-problem - 在这里,OP 似乎问了一个类似的问题,但平等,即分成两个人,成为主要问题。
我最感兴趣的是可以帮助我解决这个问题的递归关系。定义它将使我能够轻松地应用制表方法的记忆来设计解决此问题的算法。
例如这个递归:
def f(n, coins):
if n < 0:
return 0
if n == 0:
return 1
return sum([f(n - coin, coins) for coin in coins])
很诱人,但它不起作用,因为执行时:
# => f(6, [1, 2, 6]) # 14
以下是运行 S' = {1, 2, 6} 和 n = 6 的示例,以帮助我澄清模式(可能存在错误):
【问题讨论】:
-
所以您基本上是在寻找具有偶数个零件的分区数?
-
@m69:我是吗?我不确定我正在寻找分区,在我寻找的两个集合之前可能包含相同的元素,因此违反了对集合进行分区的定义。例如,对于 S = {1, 2, 6},有效解是 S1 = {1,1,1} 和 S2 = {1,1,1}。他们的交点不是空的。
-
你说得对,我看错了问题。
-
添加了自下而上的实现。这会在大约 2 秒内生成
f(500, [1, 2, 6, 12, 24, 48, 60])的答案。
标签: algorithm recursion dynamic-programming coin-change