11.动态规划之背包问-分割等和子集.py

文章讲述了如何将给定的正整数数组通过动态规划方法解决416题(LeetCode),判断是否能将其分割成两个和相等的子集。方法涉及转换为0-1背包问题,通过dp数组求解符合条件的组合。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

# # 题,这个包能装满吗?| LeetCode:416.
#
# 给你一个只包含正整数的非空数组nums 。
# 请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。
#
#
#
# 示例1:
# 输入:nums = [1, 5, 11, 5]
# 输出:true
# 解释:数组可以分割成[1, 5, 5]
# 和[11] 。
#
# 示例2:
# 输入:nums = [1, 2, 3, 5]
# 输出:false
# 解释:数组不能分割成两个元素和相等的子集。



# 转换为0-1背包问题,求怎样装物品,能使物品的价值是总价值的一半,其中物品的重量和价值相等

# 1.dp[i][j] 从前i个元素中选出若干个数字刚好能够组成j
# 2.递推公式 dp[i][j] =max(dp[i-1][j],dp[i-1][j-nums[i]]+nums[i]) 本题判断:dp[i][target] ==target
# 3.初始化dp,dp[i][0] = 0 dp[i][1]  dp[0][j] =0
# 4.确定遍历顺序
# 5.打印dp
# nums = [1, 2, 3, 5]


nums = [83,22,11,15,50,78,16,38,23,77,81,16,3,72,94,53,91,73,7,74,86,12,36,51,5,80,47,68,29,71,5,16,26,4,16,26,6,8,48,93,27,10,93,61,34,50,50,82,59,10,7,94,18,5,5,97,21,9,71,72,29,87,83,31,71,61,79,49,27,18,72,55,75,1,67,54,90,87,93,49,66,8,11,85,74,50,45,33,33,85,35,86,57,26,29,64,75,73,5,71]
nums=[1,5,11,5]

def is_true(nums):
    if sum(nums) % 2 != 0:
        return False
    target = int(sum(nums) / 2)
    if max(nums) > target:  # 最大值大于总和的一半,无法分割
        return False

    print('target=', target)
    n = len(nums)
    dp = [[0]*(target+1) for _ in range(n)]

    # 初始化
    for j in range(1, target+1):
        if j == nums[0]:
            dp[0][j] = 1
    print(dp)
    for i in range(1, n):
        for j in range(1, target+1):
            if j < nums[i]:
                dp[i][j] = dp[i - 1][j]
                # print(dp[i][j])
            else:
                dp[i][j] = dp[i - 1][j] or (dp[i - 1][j - nums[i]])
    return dp[n-1][target]

print(is_true(nums))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值