classSolution{ publicbooleancanPartition(int[] nums){ int sum = 0; for (int x : nums) { sum += x; } if (sum % 2 > 0) { returnfalse; // 总和为奇数时,不可能划分成两个相等的子集 } int n = nums.length; int C = sum / 2; int[] w = nums; boolean[] dp = newboolean[C + 1]; // 初始化,对应第 0 个物品,只有容量 c==w[i] 时,状态 dp[c]=true // 也可简化为 if (nums[0] <= C) dp[nums[0]] = true; for (int c = 0; c <= C; c++) { dp[c] = c == nums[0]; } // 自底向上迭代 for (int i = 1; i < n; i++) { for (int c = C; c >= w[i]; c--) { dp[c] = dp[c] || dp[c - w[i]]; } } return dp[C]; } }
最后一块石头的重量
有一堆石头,每块石头的重量都是正整数。
每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x <= y。那么粉碎的可能结果如下:
classSolution{ publicintlastStoneWeightII(int[] stones){ int sum = 0; for (int i : stones) { sum += i; } /* 定义 dp[i] 重量上限为 i 时背包所能装载的最大石头重量 */ int n = stones.length; int C = sum/2; int[] w = stones; int[] dp = newint[C + 1]; for (int i = 0; i < n; i++) { int curStone = stones[i]; for (int c = C; j >= w[i]; c--) { dp[c] = Math.max(dp[c], dp[c - w[i]] + w[i]); } } return sum - 2 * dp[maxCapacity]; } }