我一直在努力提出一种算法来解决这个问题。
假设我有一组数字{1, 2, 5}
,并且该集合中的每个元素都是无限制供应,而我给了另一个数字6,然后要求确定可以对元素求和以获得数字6的方式数量。出于说明目的,我这样做
1 + 1 + 1 + 1 + 1 + 1 = 6
1 + 1 + 2 + 2 = 6
2 + 2 + 2 = 6
1 + 5 = 6
1 + 1 + 1 + 1 + 2 = 6
因此,在这种情况下,程序将输出5作为路数。再次让您说要找到4的总和。
1 + 1 + 1 + 1 = 4
2 + 2 = 4
1 + 1 + 2 = 4
在这种情况下,算法将输出3作为路数
答案 0 :(得分:4)
这类似于子集总和问题。我确定您必须使用分支定界方法或回溯方法。
1)创建一个状态空间树,其中包含所有可能的情况。
0
/ | \
1 2 5
/ | \
1 2 5 ........
2)继续该过程,直到深度优先的节点总数大于或等于您想要的数量为止。
3)计算编号满足您条件的完整分支。
类似问题的python实现可以在here中找到。
答案 1 :(得分:3)
使用recursion和dynamic programming技术是一个好问题。这是使用自顶向下方法(memoization)的Python实现,以避免多次进行相同的计算:
# Remember answers for subsets
cache = {}
# Return the ways to get the desired sum from combinations of the given numbers
def possible_sums(numbers, desired_sum):
# See if we have already calculated this possibility
key = (tuple(set(numbers)), desired_sum)
if key in cache:
return cache[key]
answers = {}
for n in numbers:
if desired_sum % n == 0:
# The sum is a multiple of the number
answers[tuple([n] * (desired_sum / n))] = True
if n < desired_sum:
for a in possible_sums(numbers, desired_sum - n):
answers[tuple([n] + a)] = True
cache[key] = [list(k) for k in answers.iterkeys()]
return cache[key]
# Return only distinct combinations of sums, ignoring order
def unique_possible_sums(numbers, desired_sum):
answers = {}
for s in possible_sums(numbers, desired_sum):
answers[tuple(sorted(s))] = True
return [list(k) for k in answers.iterkeys()]
for s in unique_possible_sums([1, 2, 5], 6):
print '6: ' + repr(s)
for s in unique_possible_sums([1, 2, 5], 4):
print '4: ' + repr(s)
答案 2 :(得分:1)
对于较小的目标数量(〜1000000)和1000 {supply} n,请尝试以下操作:
提供您的号码
supply {a,b,c....}
您需要的目标
steps[n]
1种获得0的方式什么都不用
steps[0]=1
扫描到目标号码
for i from 1 to n:
for each supply x:
if i - x >=0
steps[i] += steps[i-x]
第n步将包含路数
steps[n]
以上内容的可视化: 供应{1、2、5},目标6
i = 1, x=1 and steps required is 1
i = 2, x=1 and steps required is 1
i = 2, x=2 and steps required is 2
i = 3, x=1 and steps required is 2
i = 3, x=2 and steps required is 3
i = 4, x=1 and steps required is 3
i = 4, x=2 and steps required is 5
i = 5, x=1 and steps required is 5
i = 5, x=2 and steps required is 8
i = 5, x=5 and steps required is 9
i = 6, x=1 and steps required is 9
i = 6, x=2 and steps required is 14
i = 6, x=5 and steps required is 15
一些Java代码
private int test(int targetSize, int supply[]){
int target[] = new int[targetSize+1];
target[0]=1;
for(int i=0;i<=targetSize;i++){
for(int x:supply){
if(i-x >= 0){
target[i]+=target[i-x];
}
}
}
return target[targetSize];
}
@Test
public void test(){
System.err.println(test(12, new int[]{1,2,3,4,5,6}));
}