子集和问题
问题描述:
集合A={a1, a2, a3, a4 … ,an}包含n个整数,s是一个正整数,采用动态规划的思想设计一个算法,判断集合A是否存在一个子集B,使B中的所有元素和为s,写出思想、伪代码,并分析算法的时间复杂度和空间复杂度。
采用动态规划的思想:假设P(n,sum)表示A集合中包括前n个元素的集合中,是否存在一个子集B,使B中所有元素的和为sum。
则我们可以得到递推式如下:
a.当A[n]>sum时,A[n]不纳入子集B,则此时
P(n, sum) = P(n-1, sum);
b.当A[n]<=sum时,A[n]可能是子集B中的元素,此时
P(n, sum) = P(n-1, sum-array[n]);
这两个子问题中有一个返回true,则此问题的解就是true。
对以上递推式子,自下往上递归计算,并且用一个二维数组保存前面运算的结果,便可以以多项式的时间复杂度解决此问题。
另外,初始化的条件便是:
a.当sum = 0时,不论n为多少,结果都是true。
b.当n = 0时,只要sum不是0,结果就为false。
时间复杂度与空间复杂度的分析
此算法要分别计算保存结果的数组s[n][sum]的每一个单元,因此时间复杂度为O(n*sum)
此算法要开辟一个n*sum