第九章 动态规划
背包类型 | 求解方法 |
---|---|
0/1背包 | 外循环nums,内循环target,target倒序且target>=nums[i] |
完全背包 | 外循环nums,内循环target,target正序且target>=nums[i] |
组合背包 | 外循环target,内循环nums,target正序且target>=nums[i] |
416.分割等和子集
该问题转换为在数组中找到元素和target=sum(nums)/2
即可,为0/1背包问题,dp[i]
表示是否存在子集和为i。
初始化:dp[0]=true,表示和为0,不需要选取任何元素,为真
如果和为奇数或者数组中最大值大于target
无法分成两个等和子集
go
func canPartition(nums []int) bool {
sum, maxNum := 0, 0
for _, num := range nums {
maxNum = max(maxNum, num)
sum += num
}
if sum%2 != 0 {
return false
}
target := sum / 2
if maxNum > target {
return false
}
dp := make([]bool, target + 1)
dp[0] = true
for _, num := range nums {
for i := target; i >= num; i-- {
dp[i] = dp[i] || dp[i - num]
}
}
return dp[target]
}