All along, dynamic planning is my problem, today saw a dynamic planning problem, did a long time, also think for a long time, draw on the code of others to understand this problem.
Test instructions
if The array can partitioned into subsets such, the sum of elements in both subsets are equal.
Examples:
return true subsets: [1, 5, 5], [returnfalse
The basic meaning is that given an array, it is possible to divide the array into two parts, while the two parts are the same.
When I first saw the problem, I thought of backtracking, because this is a subset of the backtracking method tree. But, it's timed out!
1. Backtracking (timeout)
1 Private BooleanFlag =false;2 Public BooleanCanpartition (int[] nums) {3Integer target = Arrays.stream (nums). Boxed (). Reduce (0, (A, B)-A +b);4 if(target% 2! = 0){5 return false;6 }7 returnBackTrack (nums, 0, 0, TARGET/2);8 }9 Ten Private Static BooleanBackTrack (intNums[],intStartintSum,inttarget) { One if(Sum = =target) { AFlag =true; - } - Else the { - for(inti = start; i < nums.length; i++){ - if(sum + nums[i] <=target) { -BackTrack (Nums, i + 1, sum +Nums[i], target); + } - } + } A returnFlag; at}
Later, this is similar to the 0-1 backpack, 0-1 backpack is also choose some items to turn, and here is the choice of some numbers, to ensure that two parts and is the same. So follow the 0-1 backpack method to do.
2. Similar to the 0-1 backpack practice
1 Public Static BooleanCanpartition (int[] nums) {2 intsum = Arrays.stream (nums). Reduce (0, integer::sum);3 if(sum% 2 = = 1)4 return false;5 Else {6Sum/= 2;7 intn =nums.length;8 //Dp[i][j] means that if we take the first I number, and the backpack capacity is J, the maximum amount of things to put9 intDp[][] =New intN [Sum + 1];Ten //Dp[0][0] For the initial state, indicating that there is nothing there is no volume, the rest of the part is initialized One for(inti = nums[0]; I <= sum; i++) { ADp[0][i] = nums[0]; - } - //traverse n numbers, which is treated as n products the for(inti = 1; I < n; i++) { - //update status After adding this item - for(intj = Nums[i]; J <= Sum; J + +) { -DP[I][J] = Math.max (Dp[i-1][j], Dp[i-1][j-nums[i]] +nums[i]); + } - } + //It's full to show the exact moment. A if(Dp[n-1][sum] = =sum) at return true; - Else - return false; - } -}
Later read the other code on the Internet, feel the other way better.
3. Other practices (dynamic planning)
1 Public BooleanCanpartition (int[] nums) {2 intsum = Arrays.stream (nums). Reduce (0, integer::sum);3 inttarget = SUM/2;4 if(sum% 2! = 0){5 return false;6 }7 Boolean[] DP =New Boolean[Target + 1];8Dp[0] =true;9 for(inti = 0; i < nums.length; i++){Ten for(intj = target; J >= Nums[i]; j--) { OneDP[J] = Dp[j] | | Dp[j-Nums[i]]; A } - } - returnDp[target]; the}
The above code is also dynamic planning, but only one-dimensional arrays are used.
Which means:
We define a DP array to indicate whether a number is the same as any of the nums of an array, for example, dp[2] to indicate whether 2 is the and of any of the nums's sets, and if so, that is true, otherwise false. So we end up looking at DP[SUM/2] (sum of the nums for the array) is true. But how do we get this DP array?
First, we get DP[SUM/2] on the line, so the length of the array is preferably sum + 1, because dp[0] is not within the scope of the problem, so DP to find out 1 ~ sum/2 directly all values, so we can get a two-dimensional table (actually a one-dimensional table, but here to demonstrate clearly, only select the two-dimensional table). The DP array defaults to FALSE, and then updates the array later.
Let's look at a table:
Algorithm-partition Equal subset Sum (Dynamic planning)