C 算法|给定数组[]和k,求k的子集数和倍数
给定一个正整数的C 算法|给定数组[]和k,求k的子集数和倍数,c,arrays,algorithm,data-structures,subset-sum,C,Arrays,Algorithm,Data Structures,Subset Sum,给定一个正整数的数组[]和另一个整数k,我必须找到其和是k的倍数的子集的数目(sum可被k整除) 比如说, array[] = {1, 2, 3, 4}, k = 3 子集和是 1 = 1 1 + 2 = 3 1 + 2 + 3 = 6 1 + 2 + 3 + 4 = 10 2 = 2 2 + 3 = 5 2 + 3 + 4 = 9 3 = 3 3 + 4 = 7 4 = 4 因此,{3,6,9}是k=3的倍数,答案是3。对于上面的相同数组和k=2,答案将是4={6,10,2,4} 如何在数
数组[]
和另一个整数k
,我必须找到其和是k
的倍数的子集的数目(sum
可被k
整除)
比如说,
array[] = {1, 2, 3, 4}, k = 3
子集和是
1 = 1
1 + 2 = 3
1 + 2 + 3 = 6
1 + 2 + 3 + 4 = 10
2 = 2
2 + 3 = 5
2 + 3 + 4 = 9
3 = 3
3 + 4 = 7
4 = 4
因此,{3,6,9}
是k=3
的倍数,答案是3
。对于上面的相同数组和k=2
,答案将是4={6,10,2,4}
如何在数组大小100万的情况下有效地实现它这是的一个近似变体,与原始版本一样,它是NP完全的(从 可以使用动态规划通过以下递归公式进行求解:
D(0,0) = true
D(0,x) = false x > 0
D(i,x) = false x < 0
D(i,x) = D(i-1,x) OR D(i-1,x-arr[i])
D(0,0)=真
D(0,x)=假x>0
D(i,x)=假x<0
D(i,x)=D(i-1,x)或D(i-1,x-arr[i])
在这里,D(i,x)
为真,当且仅当您可以使用第一个i
元素的子集来构建数字x
这可以使用动态规划进行有效计算
完成后,只需计算i
的值的数量,使D(n,k*i)=true
这将花费
O(n*W)
时间,其中n
是元素的数量,W
是元素的总和。这是元素的一个紧密变体,与原始元素一样,它是NP完全的(从元素的减少是微不足道的)
可以使用动态规划通过以下递归公式进行求解:
D(0,0) = true
D(0,x) = false x > 0
D(i,x) = false x < 0
D(i,x) = D(i-1,x) OR D(i-1,x-arr[i])
D(0,0)=真
D(0,x)=假x>0
D(i,x)=假x<0
D(i,x)=D(i-1,x)或D(i-1,x-arr[i])
在这里,D(i,x)
为真,当且仅当您可以使用第一个i
元素的子集来构建数字x
这可以使用动态规划进行有效计算
完成后,只需计算i
的值的数量,使D(n,k*i)=true
这将花费
O(n*W)
时间,其中n
是元素的数量,W
是元素的总和。这似乎是使用递归的明确用法
对于数组中的每个值
测试值本身
测试剩余数组的所有组合,包括有附加值和无附加值 这似乎是使用递归的一个明确用法 对于数组中的每个值 测试值本身
测试剩余数组的所有组合,包括有附加值和无附加值 元素和k的范围是多少?你们熟悉经典的子集和问题DP解吗?它们都在C中的整数范围内。是的,我知道经典的一个。但似乎它在这里不起作用。
两者都在C的整数范围内
我希望这是一个正确定义的大小:(假设2你熟悉子集和问题吗?显然,这个问题是NP完全的,所以如果元素在相对较小的范围内-伪多项式解可能是你能做的最好的方法,你可以像正则子集和问题解一样来做。在O(n*W)中)
,其中n
是元素数,W
是元素和元素的总和。元素和k的范围是什么?你熟悉经典的子集和问题DP解决方案吗?两者都在C的整数范围内。是的,我知道经典的一个。但似乎在这里不起作用。两者都在C的整数范围内
我希望这是一个正确的解决方案定义大小:(假设2你熟悉子集和问题吗?显然,这个问题是NP完全的,所以如果元素在相对较小的范围内-伪多项式解可能是你能做的最好的,你可以做的和正则子集和问题解一样。在O(n*W)中
,其中n
是元素的数量,W
是元素的总和。这种方法不也需要O(n*W)
空间吗?当然,这可能是可以接受的,但也可能是禁止的。@JohnBollinger,因为在每个点上只需要前一行(您总是转到D(i-1,…)
,您只需要当前行和最后一行,因此它可以在O(W)
空间中完成。没有比伪多项式时间更有效的方法了,除非P=NP,因为快速有效地解决它可以解决分区问题。您可以为O(n*k)执行权重索引modk
-时间算法。@Davidisenstat可能我遗漏了一些东西,但它不会只给出I
这样的子集和I
-但不会告诉你它的值是什么(或者存在多少这样的I
值,这是你需要的)?这种方法不也需要O(n*W)
space?这当然可以接受,但也可能是禁止的。@JohnBollinger因为您在每个点只需要前一行(您总是转到D(i-1,…)
,您只需要当前行和最后一行,所以可以在O(W)中完成
space。没有比伪多项式时间更有效的方法了,除非P=NP,因为快速有效地解决它可以解决分区问题。你可以对O(n*k)执行权重索引modk
-时间算法。@Davidisenstat可能我遗漏了一些东西,但它不会只在存在I
这样的子集与I
求和时提供给你,而不会告诉你它的值是什么(或者存在多少这样的I
值,这是你需要的)?你看到问题中的限制了吗?@redlumI没有,但它可能不会改变我的答案。如果你编写了以这种方式实现它的代码,但它不满足你的需要,那么你可以告诉我们缺少了什么。@SazzadHissainKhan光年是一种距离度量:(你看到问题中的限制了吗?@redlumI没有,但它可能不会改变我的答案。如果你编写代码以这种方式实现它,而它没有