使用集合动态编程

时间:2013-08-09 10:59:38

标签: c algorithm dynamic-programming

我在动态编程中有一个典型的问题。

我的问题是一个数组= {1,2,3,4,5,6},我必须找到所有数组的总和最多为k。如果我考虑所有的集合,它将成为指数算法。我想通过动态编程来解决这个问题。

Suppose f k =7,
My idea is 
Pass 1: {1],{2}....{6}
Pass 2: Pass1 + {1,2},{1,3},{1,4},{1,5}
Pass 3: Pass2 + {1,2,3},

我的算法停了。

我无法通过动态编程来表达这一点。任何输入?如何将这个算法制定成程序?

2 个答案:

答案 0 :(得分:1)

针对该问题的DP解决方案应遵循下一个递归公式,并自下而上构建:

f(i,0) = {{}} //a set containing only an empty set
f(0,W) = {{}} (W > 0)
f(0,W) = {} (W < 0) //an empty set
f(i,W) = f(i-1,W) [union] extend(f(i-1,w-element[i]),element[i])

函数extend(set,e)的位置是:

extend(set,e):
   for each s in set: //s is a set itself
      s.add(e) 

请注意,复杂度仍然可能是指数级的(甚至不是伪多项式),因为生成的集合数可能是指数级的,并存储在DP表中。

答案 1 :(得分:0)

您的问题是knapsack problem的一个实例,其相关决策问题已知为NP完全。这意味着大多数情况下肯定没有亚指数算法(虽然缺少数学证明)。

ZachLangleys的评论表明,即使有一个有效的问题求解器,所有解的枚举在最坏的情况下仍然是指数的,因为产生输出已经需要指数时间。

因为决策问题是NP完全的,所以计算也不容易(否则你会计算,然后测试结果是否等于0)。