分割等和子集
目录
分割等和子集
题目:
思路:
典型的01背包问题,利用套路框架做即可
注意做了优化,把原本的二维dp降低了一维
代码:
class Solution:
def canPartition(self, nums: List[int]) -> bool:
if sum(nums) % 2:
return False
= sum(nums) // 2
s = [False for _ in range(s+1)]
dp 0] = True
dp[for i in range(1,len(nums)+1):
for j in range(s,nums[i-1]-1,-1): # 容量
= dp[j] or dp[j-nums[i-1]] # 用了or操作符
dp[j] return dp[s]
更一般的套路,定义二维数组,然后二维dp
# i代表前i个物品,j代表背包容量。
class Solution:
def canPartition(self, nums: List[int]) -> bool:
if len(nums) <= 1:
return False
if sum(nums) % 2:
return False
= sum(nums) // 2
s = [[False for _ in range(s+1)] for _ in range(len(nums)+1)]
dp for i in range(len(nums)+1):
0] = True # 背包容量为0时 永远都是满的 所以为true
dp[i][for i in range(1,len(nums)+1): # 物品个数
for j in range(1,s+1): # 背包容量,最大为总和的一半,也就是需要求的
if j - nums[i-1] < 0: # 如果容量小于当前物品的重量
= dp[i-1][j]
dp[i][j] else:
= dp[i-1][j] or dp[i-1][j-nums[i-1]]
dp[i][j] if dp[i][s]: # 剪枝
return True
return dp[len(nums)][s]
'''首先,由于i是从 1 开始的,而数组索引是从 0 开始的,所以第i个物品的重量应该是nums[i-1],这一点不要搞混。
dp[i - 1][j-nums[i-1]]也很好理解:你如果装了第i个物品,就要看背包的剩余重量j - nums[i-1]限制下是否能够被恰好装满。
换句话说,如果j - nums[i-1]的重量可以被恰好装满,那么只要把第i个物品装进去,也可恰好装满j的重量;否则的话,重量j肯定是装不满的。'''