我有一个数字清单。我也有一定数目
该总和由我列表中的几个数字得出(我可能/可能不知道它是由多少个数字组成的)。是否有一种快速算法来获取可能的数字列表?用Python编写会很棒,但是伪html" target="_blank">代码也很好。(除Python:P之外,我什么都看不到)
例
list = [1,2,3,10]
sum = 12
result = [2,10]
注意:
我确实知道算法,可以从大小为n的列表中找到哪些数字总和为另一个数字(但是我无法读取C#,也无法检查它是否满足我的需求。我在Linux上,尝试使用单声道,但我遇到错误,我不知道如何工作C#:(而且
该问题简化为0-1背包问题,您尝试在其中找到具有精确总和的集合。解决方案取决于约束条件,一般情况下,此问题是NP-
Complete。
但是,如果最大搜索总和(称为S
)不太高,则可以使用动态编程解决问题。我将使用递归函数和备忘录对其进行解释,这比自下而上的方法更容易理解。
让我们对一个函数进行编码f(v, i, S)
,以使其返回v[i:]
恰好等于的子集数S
。为了递归地解决它,首先我们必须分析基数(即:v[i:]
为空):
S == 0:的唯一子集的[]
总和为0,因此它是有效子集。因此,该函数应返回1。
S!= 0:由于的唯一子集的[]
总和为0,因此没有有效的子集。因此,该函数应返回0。
然后,让我们分析递归情况(即:v[i:]
不为空)。有两种选择:将数字包括v[i]
在当前子集中,或不包括。如果包含v[i]
,那么我们正在寻找具有sum的子集S - v[i]
,否则,我们仍在寻找具有sum的子集S
。该功能f
可以通过以下方式实现:
def f(v, i, S):
if i >= len(v): return 1 if S == 0 else 0
count = f(v, i + 1, S)
count += f(v, i + 1, S - v[i])
return count
v = [1, 2, 3, 10]
sum = 12
print(f(v, 0, sum))
通过检查f(v, 0, S) > 0
,您可以知道是否有解决问题的方法。但是,此代码太慢,每个递归调用都产生两个新的调用,从而导致O(2 ^
n)算法。现在,我们可以应用备忘录以使其在时间O(n * S)中运行,如果S
不是太大,它将更快:
def f(v, i, S, memo):
if i >= len(v): return 1 if S == 0 else 0
if (i, S) not in memo: # <-- Check if value has not been calculated.
count = f(v, i + 1, S, memo)
count += f(v, i + 1, S - v[i], memo)
memo[(i, S)] = count # <-- Memoize calculated result.
return memo[(i, S)] # <-- Return memoized value.
v = [1, 2, 3, 10]
sum = 12
memo = dict()
print(f(v, 0, sum, memo))
现在,可以对g
返回一个总和的子集的函数进行编码S
。为此,仅在至少有一个包含元素的解决方案时才添加元素就足够了:
def f(v, i, S, memo):
# ... same as before ...
def g(v, S, memo):
subset = []
for i, x in enumerate(v):
# Check if there is still a solution if we include v[i]
if f(v, i + 1, S - x, memo) > 0:
subset.append(x)
S -= x
return subset
v = [1, 2, 3, 10]
sum = 12
memo = dict()
if f(v, 0, sum, memo) == 0: print("There are no valid subsets.")
else: print(g(v, sum, memo))
免责声明:此解决方案表示[10,10]有两个子集,总和为10。这是因为它假定前十个与后十个不同。可以将算法固定为假定两个十个相等(并因此回答一个),但这有点复杂。
这个问题是在谷歌编程采访中提出的。我想到了两种方法: > 找出长度的所有子序列。这样做时,计算两个元素的和,并检查它是否等于k。如果是,请打印“是”,否则继续搜索。这是一种暴力手段。 按非降序排列数组。然后从数组的右端开始遍历数组。假设我们有一个排序数组,{3,5,7,10},我们希望总和是17。我们将从元素10开始,索引=3,让我们用“j”来表示索引。然后包含当前元素并计算所需的_sum=sum
我一直在学习动态规划,我想通过打印出所有相加为一个数字的子集来进一步研究经典的子集和问题。我该怎么做呢?到目前为止,我知道如何根据是否存在相加的子集来打印true或false 如果可能,我想返回所有子集的数组。
所以我一直在尝试制作某种计算器工具。其中一个功能是检查一个数字的因子是否与某个数相乘,但同时又与另一个数相乘。这有助于分解三项式。我找到了原因,但我不知道如何继续。这就是我目前所拥有的 请记住,我的程序的架构是调用所有其他函数的主类。 示例:X^2 9x 20=(x 5)(x 4) 4*5 = 20 4 5 = 9
问题内容: 如果我有一个PHP数组: 带有值: 我有一个变量: 如何返回值?: 因为那是数组中最接近38(递增)的值? 问候, 泰勒 问题答案:
每个数字都应该大于或等于另一个数字。如果所有数字相等,则返回false。 例子: 通常的方式是不断地除以10,然后比较余数。 null null