📌  相关文章
📜  从给定的Array元素中获得给定的Sum的方法数量(1)

📅  最后修改于: 2023-12-03 15:22:01.783000             🧑  作者: Mango

从给定的Array元素中获得给定的Sum的方法数量

给定一个包含若干整数的数组和一个整数sum,编写一个函数来计算从该数组中选择元素进行加法操作并得到给定sum的方法数量。数组中的元素可以重复使用。

示例
arr = [2, 4, 6]
sum = 6

# 输出:3
# 解释:可以通过以下三种方式得到和为6:
# 1. [2, 2, 2]
# 2. [2, 4]
# 3. [6]
解题思路

这是一个典型的背包问题,可以使用动态规划来解决。使用一个一维数组dp来记录计算结果,其中dp[i]表示凑出i的方法数。则有:

$$ dp[i] = \sum_{j=0}^{len(arr)-1} dp[i-arr[j]] $$

其中,$len(arr)$ 表示数组arr的长度。也就是说,如果目标sum是7,那么凑出7的方法数就是凑出6的方法数 + 凑出3的方法数 + 凑出1的方法数。其中凑出6的方法数又是通过凑出5的方法数 + 凑出2的方法数 + 凑出0的方法数得到。

边界条件是: $dp[0] = 1$,因为凑出0的方法只有一种,就是不选。

最终结果是 $dp[sum]$。

代码实现
def count_subset_sum(arr, sum):
    n = len(arr)
    dp = [0] * (sum+1)
    dp[0] = 1
    
    for i in range(1, sum+1):
        for j in range(n):
            if i >= arr[j]:
                dp[i] += dp[i-arr[j]]
    
    return dp[sum]
时间复杂度

时间复杂度为 $O(sum*n)$,其中n是数组的长度,sum是需要凑出的目标和。这个算法也可以使用滚动数组来将空间复杂度优化到 $O(sum)$,但这里就不再赘述了。