背包型动态规划——背包问题6

给出一个都是正整数的数组 nums,其中没有重复的数。从中找出所有的和为 target 的组合个数。

示例:

输入: nums = [1, 2, 4] 和 target = 4
输出: 6
解释:
可能的所有组合有:
[1, 1, 1, 1]
[1, 1, 2]
[1, 2, 1]
[2, 1, 1]
[2, 2]
[4]

1、题目分析

和背包问题5唯一的区别是:组合中数字可以按照不同的顺序组合

2、确定状态

最后一步:最后一个物品重量是多少

• 如果最后一个物品重量是A0 , 则要求有多少种组合能拼成Target – A0

• 如果最后一个物品重量是A1 , 则要求有多少种组合能拼成Target – A1

• …

• 如果最后一个物品重量是AN-1, 则要求有多少种组合能拼成Target – AN-1

因此我们可以假设f[i]表示有多少种组合能拼出重量i

3、转移方程

假设f[i]表示有多少种组合能拼出重量i
在这里插入图片描述

4、初始条件和边界情况

f[0]=1:表示有1种组合能拼出重量0

如果i<Aj,则对应的f[i-Aj]不加入f[i]

5、计算顺序

从小到大计算,结果为f[Target]

时间复杂度: O(N*Target),空间复杂度:O(Target)

6、代码实现

class Solution:
    """
    @param nums: an integer array and all positive numbers, no duplicates
    @param target: An integer
    @return: An integer
    """
    def backPackVI(self, nums, target):
        # write your code here
        if target==0 or len(nums)==0:
            return 0
        dp=[0]*(target+1)
        dp[0]=1
        for i in range(1,target+1):
            for j in nums:
                if i>=j:
                    dp[i]+=dp[i-j]
        return dp[target]

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值