import java.util.*; /** * NC214 分割等和子集 * @author d3y1 */ public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param nums int整型一维数组 * @return bool布尔型 */ public boolean partition (int[] nums) { return solution1(nums); // return solution2(nums); } /** * 动态规划: 01背包 * * dp[i]表示背包大小为i时所能凑成的最大整数和 * * dp[j] = Math.max(dp[j], dp[j-nums[i]]+nums[i]) , nums[i]<=j<=v * * @param nums * @return */ private boolean solution1(int[] nums){ int n = nums.length; int sum = 0; for(int i=0; i<n; i++){ sum += nums[i]; } // 所有整数和为奇数 if(sum%2 == 1){ return false; } int v = sum/2; int[] dp = new int[v+1]; for(int i=0; i<n; i++){ // 某个整数大于一半 if(nums[i] > v){ return false; } // 某个整数等于一半 if(nums[i] == v){ return true; } for(int j=v; j>=nums[i]; j--){ dp[j] = Math.max(dp[j], dp[j-nums[i]]+nums[i]); } } // 是否能恰好装满 return dp[v]==v; } /** * 动态规划 * * dp[i]表示背包大小为i时是否能恰好装满 * * dp[j] = dp[j] | dp[j-nums[i]] , nums[i]<=j<=v * * @param nums * @return */ private boolean solution2(int[] nums){ int n = nums.length; int sum = 0; for(int i=0; i<n; i++){ sum += nums[i]; } // 所有整数和为奇数 if(sum%2 == 1){ return false; } int v = sum/2; boolean[] dp = new boolean[v+1]; dp[0] = true; for(int i=0; i<n; i++){ // 某个整数大于一半 if(nums[i] > v){ return false; } // 某个整数等于一半 if(nums[i] == v){ return true; } for(int j=v; j>=nums[i]; j--){ dp[j] = dp[j] | dp[j-nums[i]]; } } // 是否能恰好装满 return dp[v]; } }