繁体   English   中英

使k个元素的总和等于p的方式数

[英]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]包含总和为ik/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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM