[LeetCode] 494. Objectives and (0-1 knapsack, DP)

topic

Given an array of non-negative integer, a1, a2, ..., an, and a number of goals, S. Now you have two symbols + and -. For any integer array, you can from + or - to select a symbol added earlier.

And the final array can return all the way to add the number of symbols is the target number of S.

Example 1:

Input: nums: [1, 1, 1, 1, 1], S: 3
Output: 5
Explanation:

-1+1+1+1+1 = 3
+1-1+1+1+1 = 3
+1+1-1+1+1 = 3
+1+1+1-1+1 = 3
+1+1+1+1-1 = 3

There are 5 ways to make the ultimate goal and three.
note:

An array of non-empty, and a length of no more than 20.
The initial array and not more than 1,000.
The end result can be returned able to save the 32-bit integer.

Source: stay button (LeetCode)
link: https://leetcode-cn.com/problems/target-sum
copyrighted by deduction from all networks. Commercial reprint please contact the authorized official, non-commercial reprint please indicate the source.

answer

The problem can be divided into two digital collections (subsets and I set).
(With) a subset of sum- I Set sum = S
(simultaneously adding both sides of the subset sum + I current sum) subset sum + I current sum + subset sum- I Set sum = subset sum + I current sum + S
(i.e.) 2 * sum = a subset of set S + SUM
(i.e.) subset sum = (set sum + S) / 2
so that problem into Qiuzi set and how many combinations of fixed value . Each number can be selected or not selected, can be used for 0-1 knapsack problem solving.
When traversed num, DP [j] represents only traversed before and num num, and j is the number of combinations of species. , And the classic 0-1 knapsack problem can be one-dimensional array than circumstances, understanding 0-1 knapsack problem.

other

todo can also be solved with dfs.

Code

class Solution {
    public int findTargetSumWays(int[] nums, int S) {
        int setSum=0;
        for(int num:nums) {
            setSum+=num;
        }
        
        if((setSum+S)%2==1) {
            return 0;
        }
        
        int subSetSum=(setSum+S)/2;
        int[] dp=new int[subSetSum+1];
        dp[0]=1;
        for(int num:nums) {
            for(int j=subSetSum;j>=num;--j) {
                dp[j]+=dp[j-num];
            }
        }
        return dp[subSetSum];
    }
}

Guess you like

Origin www.cnblogs.com/coding-gaga/p/11716714.html