我正在寻找以下问题的答案。
给定一组整数(无重复项)和一个和,找出集合元素的所有可能组合,并求和。解的顺序并不重要(解{2,2,3}和{3,2,2}是相等的)。
请注意,最终组合不需要是集合,因为它可以包含重复。
示例:集合{2,3,5}和10
结果:{2, 2, 2, 2, 2},{2,2,3,3},{2,3,5},{5,5}
我已经研究过子集和问题以及硬币兑换问题,但不能使它们适应我的需要。我不太熟悉动态规划,所以它可能是可行的,但我无法理解。
由于我处理的是一个相当大的元素集(大约50个),因此预计算所有元素集不是一个选项,因为这将需要很长时间。最好是从子集和表中提取不同的解决方案(如果可能的话)。
任何建议,提示或示例代码将不胜感激!
解决方案复杂性:
其中M是总和的值,n是设置的大小
int numberOfSums(Set<Integer> values, int sum) {
// sumCount[i] -> number of ways to get sum == i
int sumCount[] = new int[sum+1];
sumCount[0] = 1;
for(int v : values) {
for(int i=0; i<=sum-v; ++i)
sumCount[i+v] += sumCount[i];
}
return sumCount[sum];
}
下面是计算答案的Haskell函数:
partitions 0 xs = [[]]
partitions _ [] = []
partitions n (xxs@(x:xs)) | n < 0 = []
| otherwise = (map (x:) (partitions (n-x) xxs)) ++ partitions n xs
例子:
*Main> partitions 1 [1]
[[1]]
*Main> partitions 5 [1..5]
[[1,1,1,1,1],[1,1,1,2],[1,1,3],[1,2,2],[1,4],[2,3],[5]]
*Main> length $ partitions 10 [1..10]
42
*Main> length $ partitions 20 [1..20]
627
*Main> length $ partitions 40 [1..40]
37338
*Main> partitions 10 [1,2,4]
[[1,1,1,1,1,1,1,1,1,1],[1,1,1,1,1,1,1,1,2],[1,1,1,1,1,1,2,2],[1,1,1,1,1,1,4],[1,1,1,1,2,2,2],[1,1,1,1,2,4],[1,1,2,2,2,2],[1,1,2,2,4],[1,1,4,4],[2,2,2,2,2],[2,2,2,4],[2,4,4]]
半现场演示
这被称为变更问题,是动态编程中的一个经典例子。
一些较早的答案计算了解决方案的总数,而问题要求列举可能的解决方案。
您没有用语言标记您的问题,因此这里有一个Python实现。通过使用您的语言的“bag”数据类型(注意,计数器是Python的“bag”)使其适应您喜欢的任何语言。
from collections import Counter
def ways(total, coins):
ways = [[Counter()]] + [[] for _ in range(total)]
for coin in coins:
for i in range(coin, total + 1):
ways[i] += [way + Counter({coin: 1}) for way in ways[i-coin]]
return ways[total]
输出数据类型是包的列表。打印它们的演示用法:
>>> from __future__ import print_function # for Python 2 compatibility
>>> for way in ways(total=10, coins=(2,3,5)):
... coins = (coin for coin,count in way.items() for _ in range(count))
... print(*coins)
...
2 2 2 2 2
2 2 3 3
2 3 5
5 5
我在一次采访中被问到以下问题。虽然我用n元树回答了这个问题,但有人告诉我这还不够好。所以,我很好奇,什么是它的最佳解决方案。 输入:整数数组:[2,3,7]和总和:10 输出:加起来等于和的所有数组元素组合(例如2、2、3、3、7等) 谢了小泰
给定一个2d数组,我需要返回一个具有路径的矩阵,该路径递归地求和到给定的数字。 路径矩阵应为零,但总计为给定数字的路径除外,该路径将标记为1。 路径只能在 我尝试过所有的可能性,首先检查我是否已经去过下一个街区。 问题是在一些迭代之后,它会停止,并且不会返回并再次将块清除为0。 给定 在通话中 我以为算法会回来 我得到 相反 调用paintPath(mat1400,path,0,0);我想 或 问
我遇到的问题如下: 对于给定的不同十进制数字数组(0,1,2,3...,8,9)编写一个递归函数,返回由给定数字组成的所有自然数的总和。例如,对于数组{1,2},您将获得12 21 2 1 = 36 我想的是如果你有一个数组1,2,3 您可以将最后一个数字“放在一边”,并将剩下的较小的一组按如下方式排列: 1 2 3 2 1 3 2 3 1 3 3 这将是10*[perm(1,2)]3*(重复次数
我知道强力解O(n^2),我想要另一个解O(n),还是O(n,log,n)?
我正在尝试构造一个程序,该程序将获取一个int({1,2,3})数组和一个长度值,并计算该数组的所有可能组合。 例如: 这将输出: 但是当我尝试在 for 循环中调用可能的梳子时,我不断收到堆栈溢出错误 }
问题陈述如下: 当帖子说解决方案对负数不起作用时,它指的是哪些输入情况?