解题思路:
该问题相当于
能否从数组中挑选出若干个元素, 它们的和等于所有元素总和的一半
dp[i][j]
代表前i
个数值, 其选择数字总和不超过j
的最大价值
状态转移方程:
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - nums[i]] + nums[i])
class Solution {
public boolean canPartition(int[] nums) {
int n = nums.length;
int sum = 0;
for(int num : nums){
sum += num;
}
int target = sum / 2;
if(target * 2 != sum) return false;
int[][] arr = new int[n][target + 1];
for(int j = 0; j <= target; j++){
arr[0][j] = j >= nums[0] ? nums[0] : 0;
}
for(int i = 1; i < n; i++){
int tmp = nums[i];
for(int j = 0; j <= target; j++){
int no = arr[i - 1][j];
int yes = j >= tmp ? arr[i - 1][j - tmp] + tmp : 0;
arr[i][j] = Math.max(no, yes);
}
}
return arr[n - 1][target] == target;
}
}
class Solution {
public boolean canPartition(int[] nums) {
int n = nums.length;
int sum = 0;
for(int num : nums){
sum += num;
}
int target = sum / 2;
if(target * 2 != sum) return false;
boolean[][] dp = new boolean[n + 1][target + 1];
dp[0][0] = true;
for(int i = 1; i <= n; i++){
int t = nums[i - 1];
for(int j = 0; j <= target; j++){
boolean no = dp[i - 1][j];
boolean yes = j >= t ? dp[i - 1][j - t] : false;
dp[i][j] = no | yes;
}
}
return dp[n][target];
}
}