![](/img/trans.png)
[英]Number of ways to choose elements from array if the sum of the group is at least K
[英]Number of ways such that sum of k elements equal to p
给定一系列整数,它们之间的关系是一个数字等于前两个数字的和,而起始整数是1
系列-> 1,2,3,5,8,13,21,34,55
求出使k个元素的总和等于p的方法的数量。我们可以使用任意数量的元素。
p = 8
k = 4。
因此,方法数量为4。
1,1,1,5
1,1,3,3
1,2,2,3
2,2,2,2
我可以通过递归解决这个问题。我在这里感觉到动态编程,但我没有怎么做。可以在更少的时间内完成吗?
编辑我忘记提及数字的顺序无关紧要,并且将被计数一次。 对于ex = 3->(1,2)和(2,1)。这里路数只能是1。
编辑 :自发布以来,海报已更改了原始问题。 我的算法仍然有效,但也许可以改进。 最初的问题有n个任意输入数字(他现在将其修改为斐波那契数列)。 要将我的算法应用于修改后的帖子,请通过仅截取小于p的元素(假设有n个)来截断该序列。
这是一个n^(k/2)
算法。 ( n
是序列中的元素数)
请使用长度为p
的表,以使table[i]
包含总和为i
的k/2
元素的所有组合。 例如,在您提供的示例数据中, table[4]
包含{1,3}
和{2,2}
。
编辑:如果空间是禁止的,则可以使用有序链接列表来完成相同的算法,在此仅存储非空表条目。 链表必须是双向的:向前和向后,这使得算法的最后一步更加简洁。
一旦计算完该表,然后只要将每个table[j]
与每个table[pj]
都table[pj]
非空,就可以得到所有解。
要获取该表,请将整个对象初始化为空。 然后:
For i_1 = 0 to n-1:
For i_2 = i_1 to n-1:
...
For i_k/2 = i_k/2-1 to n-1:
sum = series[i_1] + ... + series[i_k/2]
if sum <= p:
store {i_1, i_2, ... , i_k/2 } in table[sum]
看起来“可变循环数”似乎无法实现,但实际上可以用长度为k/2
的数组来完成,该数组跟踪每个i_`的位置。
让我们回到您的数据,看看我们的表看起来如何:
table[2] = {1,1}
table[3] = {1,2}
table[4] = {1,3} and {2,2}
table[5] = {2,3}
table[6] = {1,5}
table[7] = {2,5}
table[8] = {3,5}
通过将table[2]
与table[6]
, table[3]
与table[5]
以及table[4]
与table[4]
组合,找到解决方案。 因此,解决方案是:{1,1,1,5} {1,2,2,3},{1,1,3,3},{2,2,2,2},{1,3,2 ,2}。
您可以使用动态编程。 令C(p, k)
为相加k
元素等于p
的方式数, a
为元素数组。 然后
C(p, k) = C(p - a[0], k - 1) + C(p - a[1], k - 1) + .... + C(p - a[n-1], k - 1)
然后,您可以使用记忆来加快代码速度。
暗示:
您的问题是众所周知的。 它是和集问题,是背包问题的一种变体。 检查一下这个很好的解释。 和集问题
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.