题目链接
题目描述
解题思路
可以看成是背包问题:从n个物品中选取m个物品,每个物品只能选择一次,每个物品的价值对应p,是否能恰好选出价值和为k的选法;
记dp[i][j] 表示 是否能从前i个物品中恰好选择价值和为j的选法;对于每个物品而言,只有两种情况:选和不选,因此状态转移方程为:
if(当前物品i价值 > j) {// 不选择i,往前走dp[i][j] = dp[i-1][j];} else{// 选择i,往前走 | 不选择i,往前走 两者都可以进行判断取或dp[i][j] = dp[i-1][j] | dp[i-1][j-1];}
实现代码:
class Solution {public boolean canPartition(int[] nums) {int len = nums.length;int sum = nums[0];int max = sum;for (int i = 1; i < len; i++) {sum += nums[i];max = max > nums[i] ? max : nums[i];}if (sum % 2 != 0) {return false;}int target = sum / 2;if (target < max) {return false;}boolean[][] dp = new boolean[len][target + 1];for (int i = 0; i < len; i++) {dp[i][0] = true;}dp[0][nums[0]] = true;for (int i = 1; i < len; i++) {int val = nums[i];for (int j = 1; j <= target; j++) {if (j >= val) {dp[i][j] = dp[i - 1][j - val] || dp[i - 1][j];} else {dp[i][j] = dp[i - 1][j];}}}return dp[len - 1][target];}}
