分析
完全填满背包
F(n,c)这里表示使用n个物品能否将容量为C的背包填满,这里是个布尔值
或者用i-1个物品填满背包(此时不用第i个物品),或者用i-1个物品填满c-w(i)的物品(此时可以用w(i)去填满)
code
记忆化搜索
class Solution {//memo[i][c]表示使用索引为[0...i]的这些元素,是否可以完全填充一个容量为c的背包//-1表示未计算,0表示不可以填充,1表示可以填充private int[][] memo;public boolean canPartition(int[] nums) {int sum = 0;for(int i:nums)sum+=i;if(sum%2!=0)return false;memo = new int[nums.length][sum/2+1];for(int i=0;i<nums.length;i++)Arrays.fill(memo[i],-1);return tryPartition(nums,nums.length-1,sum/2);}//使用nums[0....index],是否可以完全填充一个容量为sum的背包private boolean tryPartition(int[] nums,int index,int sum){if(sum==0)return true;if(sum<0||index<0)return false;if(memo[index][sum]!=-1)return memo[index][sum]==1;memo[index][sum] = (tryPartition(nums,index-1,sum)||tryPartition(nums,index-1,sum-nums[index]))?1:0;return memo[index][sum] == 1;}}
动态规划
class Solution {public boolean canPartition(int[] nums) {int sum = 0;for(int i:nums)sum+=i;if(sum%2!=0)return false;int n = nums.length;int C = sum/2;boolean[] memo = new boolean[C+1];for(int i=0;i<=C;i++)memo[i]=(nums[0]==i);for(int i=1;i<n;i++)for(int j=C;j>=nums[i];j--)memo[j]=memo[j]||memo[j-nums[i]];return memo[C];}
