具有非零目标总和的子集和变体
Subset sum variant with a non-zero target sum
我有一个整数数组,需要对其应用子集和算法的变体,除了不是找到一组总和为 0 的整数,而是我试图找到一组总和为 n
的整数。 我不清楚如何将标准子集和算法之一适应这种变体,并希望对这个问题有任何见解。
这是子集和问题,它是NP-Complete(NP-Complete问题没有已知的有效解决方案),但是如果你的数字是相对较小的整数 - 有一个有效的伪多项式解,在循环之后
:D(x,i) = false x<0
D(0,i) = true
D(x,0) = false x != 0
D(x,i) = D(x,i-1) OR D(x-arr[i],i-1)
稍后,您需要退后一步,查看您决定在生成的矩阵上"减少"(获取元素)的位置,以及您决定不"减少"(不获取元素
)的位置。此线程和此线程讨论如何获取类似问题的元素。
这是一个python代码(取自我链接到的线程)可以解决问题。
如果你不熟悉python - 把它当作伪代码来阅读,很容易理解python!。
arr = [1,2,4,5]
n = len(arr)
SUM = 6
#pre processing:
D = [[True] * (n+1)]
for x in range(1,SUM+1):
D.append([False]*(n+1))
#DP solution to populate D:
for x in range(1,SUM+1):
for i in range(1,n+1):
D[x][i] = D[x][i-1]
if x >= arr[i-1]:
D[x][i] = D[x][i] or D[x-arr[i-1]][i-1]
print D
#get a random solution:
if D[SUM][n] == False:
print 'no solution'
else:
sol = []
x = SUM
i = n
while x != 0:
possibleVals = []
if D[x][i-1] == True:
possibleVals.append(x)
if x >= arr[i-1] and D[x-arr[i-1]][i-1] == True:
possibleVals.append(x-arr[i-1])
#by here possibleVals contains 1/2 solutions, depending on how many choices we have.
#chose randomly one of them
from random import randint
r = possibleVals[randint(0,len(possibleVals)-1)]
#if decided to add element:
if r != x:
sol.append(x-r)
#modify i and x accordingly
x = r
i = i-1
print sol
您可以使用动态编程来解决此问题。
让我们假设:
-
N
- 是所需的总和(您的第一个输入)。 -
M
- 是可用的汇总数(您的第二个输入)。 - 一...aM - 是可用的总和。
-
f[x]
是true
当你可以达到x
的总和时,否则false
现在的解决方案:
最初f[0] = true
和f[1..N] = false
- 我们只能达到零的总和,而无需取任何求和。
现在,您可以遍历所有i,其中 i
在 [1..M] 中,并执行下一个操作:
+ ai] || f[x],对于 [M..ai] - 处理顺序是相关的!
最后输出 f[N]。
此解决方案具有 O(N*M) 的复杂性,因此当您具有大量输入数字或大量总和时,它不是很有用。
相关文章:
- 给定一个向量,如何找到该向量的所有子集和的原始索引
- 这种用于查找连续子数组中最大和的递归算法有什么优势吗?
- 斐波那契数列部分和的最后一位数字
- 如何有效地找到数组中三元组和的最小差异?
- 用于子集字符串的 Rcpp 函数
- 为什么我的子集和方法不正确?
- 从小于或等于某个 N 的数字列表中最小化或找到 n 个理想的子集和
- 使用递归从子集和中查找最大和
- 计算校验和的逐位运算符
- 实现伪多项式DP子集和
- 找到 2 个相等和的子序列,最大总和?
- 返回混合 \ 和 / 的文件系统路径字符串方法
- *、/ 和 % 的定义如何保证 a/b * b + a%b == a
- 带有空格和","的Cin
- 在这里,我编写了一个使用 2 维数组并打算执行行和的 C++ 代码,但它没有给出正确的输出
- 为什么这种递归子集和算法会导致指针分配错误
- 在二叉搜索树中查找最小和的算法改进
- 与具有 2,3 和更多整数的子集和相关的想法
- 使用 c++ 的子集和递归
- 具有非零目标总和的子集和变体