python硬币多少组合方式_硬币组合的完全搜索算法

这个问题类似于硬币兑换问题,但有点不同。在

问题是这样说的:你有一套硬币,你知道硬币的价值和每种硬币的数量。你想知道你能从这些硬币的非空分组中得到多少不同的总数。在

例如coins = [1, 2, 3]和quantity=[1, 2, 2],有11个可能的和,基本上都是1-11之间的数字。在

阵列硬币的长度最多只能达到20,但是数量[x]可以达到10^5。在

什么是有效的可能的算法解决方案。收集如此大量的所有可能的组合将花费永远的时间。有没有一个数学公式可以确定答案?我看不出它会如何运作,尤其是它需要不同的金额。在

我在考虑根据硬币和它的数量生成一个数组。基本上是多重的:[ [1],

[2, 4],

[3, 6]]

然后必须从每个数组中选择1或无。在

^{pr2}$

我似乎想不出一个好的算法来实现这一点。做嵌套循环可能太慢,因为可能有20个不同的硬币,每个硬币可能有大量。在

另一个可能的解决方案是循环1到最大。其中最大值是所有硬币的总和乘以其相关数量。但问题在于确定是否存在一个子集,它将等于这个数。我知道有一种动态规划算法(subset sum)来确定是否存在一个子集,该子集加起来就是某个值,但是数组是什么呢?在

对于这个例子,它工作得很好,列表为[1,2,4,3,6],目标和为11,那么在DP中计算“True”将得到11。但例如coins = [10,50,100]和{}。答案是9个可能的和,但是如果使用子集和DP algo将得到21个“真”。如果提供的列表是[10,50100100]或[10,50100]基于[[10],[50,100],[100]]

最好使用python解决方案,但不是必需的。在

下面是我当前的代码,在[105100]硬币的例子中得到了21。在def possibleSums(coins, quantity):

def subsetSum(arr,s):

dp = [False] * (s + 1)

dp[0] = True

for num in sorted(arr):

for i in range(1, len(dp)):

if num <= i:

dp[i] = dp[i] or dp[i - num]

return sum(dp)

maximum = sum((map(lambda t: t[0] * t[1], zip(coins, quantity))))

combinations = [[]]*len(coins)

for i,c in enumerate(coins):

combinations[i] = [ j for j in range(c,(c*quantity[i])+1,c) ]

array = []

for item in combinations:

array.extend(item)

print(subsetSum(array,maximum) - 1)

保证约束:1 ≤ coins.length ≤ 20,

1 ≤ coins[i] ≤ 10^4.

quantity.length = coins.length,

1 ≤ quantity[i] ≤ 10^5.

保证(数量[0]+1)*(数量[1]+1)*。。。*(数量[数量.长度-1]+1)&lt;=10^6。在

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值