416. 分割等和子集
给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。
思路
乍一看与背包问题无关,但其实可以转化成01背包问题:给定N个物品,每个物品的重量为nums[i],和一个容量为sum/2的背包,问是否存在一种方法,可以恰好装满背包。
- 定义dp[i][j]:用前i个数字,是否可能恰好凑成和为i。
- base case:dp[0][…] = False, dp[…][0] = True
- 状态转移:
不用第i个数字:dp[i][j] = dp[i-1][j]。(不用第i个数字,当前背包是否能恰好装满取决于上一个状态)
用第i个数字:dp[i][j] = dp[i-1][j-nums[i-1]]。(当前状态是否能装满背包,取决于不用第i个数字时,背包剩余空间,即空间为j-nums[i-1]时,是否能恰好装满)
综上,dp[i][j] = dp[i-1][j] || dp[i-1][j-nums[i-1]]。 - 目标:返回dp[n][sum/2]
for(int i=1; i<=n; i++) {
for(int j=1; j