题目详见 416.分割等和子集
解题思路
- 一个集合分成两个相等子集,等价于背包容量为子集大小的01背包问题,且容量和价值是相同的
- dp[i] i表示 容量为i ,dp[i] 表示价值
- 初始化很重要!题目限定长度[1,200],并且每个值是[0,100],所以最大容量也就是10000
Talk is cheap,show me the code
class Solution:
def canPartition(self, nums: List[int]) -> bool:
# 1. 确定dp数组及下标含义
# 2. 确定递推公式
# 3. 初始化dp数组
# 4. 确定遍历顺序
# 5. 验证dp数组
sum_nums = sum(nums)
if sum_nums %2 != 0:
return False
n = sum_nums // 2 # dp[n] n表示nums的一个子集 dp表示和
# 这道题 物品价值和重量是相等的
# 初始化dp len 是 1,200 最大值 100 所以sum/ 2 最大等于10000
dp = [0] * 10001
for i in range(len(nums)): # 物品
for j in range(n, nums[i]-1,-1): # 只有容量大于num[i] 才会被考虑是否放入
# 背包 滚动数组需要逆序遍历
dp[j] = max(dp[j],dp[j-nums[i]] + nums[i])
return n == dp[n]