# # 题,这个包能装满吗?| 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))
11.动态规划之背包问-分割等和子集.py
于 2023-12-04 16:08:33 首次发布