Given an array arr of n integers and an integer K, count the number of subsets of the given array that have a sum equal to K. Return the result modulo 109+7.
Input: arr = [2, 3, 5, 16, 8, 10], K = 10
Output: 3
Explanation: The subsets are [2, 8], [10], and [2, 3, 5].
Input: arr = [1, 2, 3, 4, 5], K = 5
Output: 3
Explanation: The subsets are [5], [2, 3], and [1, 4].
Input: arr = [2, 2, 2, 2], K = 4
The idea is to generate all pssible subsets and whenever a single subsets is found whose sum is equal to the given target, simply count it. As, all the subsets needs to generated, recursion can be used to solve this problem.
So, f(ind, target) will count the number of subsets that exists in the array from index 0 to 'ind', whose sum is equal to target.
Do not include the current element in the subset: First try to find a subset without considering the current index element. For this, make a recursive call to f(ind-1,target).
Include the current element in the subset: Now try to find a subset by considering the current index element as part of subset. As the current element(arr[ind]) is included, the remaining target sum will be target - arr[ind]. Therefore, make a function call of f(ind-1,target-arr[ind]).
Note: Consider the current element in the subset only when the current element is less or equal to the target.
/*It is pseudocode and it is not tied to
any specific programming language*/
f(ind, target){
not pick = f(ind-1, target)
pick = 0
if(target <= arr[ind]){
pick = f(ind-1, target - arr[ind])
}
}
/*It is pseudocode and it is not tied to
any specific programming language*/
f(ind, target){
not pick = f(ind-1, target)
pick = 0
if(target <= arr[ind]){
pick = f(ind-1, target - arr[ind])
}
return pick + not pick
}
#include <bits/stdc++.h>
using namespace std;
class Solution{
int modulo = 1e9+7;
private:
/*Function to count the number of
subsets with sum k using recursion*/
int findWaysUtil(int ind, int target, vector<int>& arr) {
/* Base case: If the target sum
is 0, we found a valid subset*/
if (target == 0)
return 1;
/* Base case: If we have considered all elements
and the target is still not 0, return 0*/
if (ind == 0)
return (arr[0] == target) ? 1 : 0;
// Exclude the current element
int notTaken = findWaysUtil(ind - 1, target, arr);
/* Include the current element if
it doesn't exceed the target*/
int taken = 0;
if (arr[ind] <= target)
taken = findWaysUtil(ind - 1, target - arr[ind], arr);
/* Return the result. Also, take
modulo for the code to be accepted*/
return (notTaken + taken)%modulo;
}
public:
//Function to find out number of subsets with sum k
int perfectSum(vector<int>&arr, int K){
int n = arr.size();
//Return the result
return findWaysUtil(n - 1, K, arr);
}
};
int main() {
vector<int> arr = {1, 2, 2, 3};
int k = 3;
//Create an instance of Solution class
Solution sol;
//Print the result
cout << "The number of subsets found are " << sol.perfectSum(arr, k);
return 0;
}
import java.util.Arrays;
class Solution {
private static final int MODULO = 1000000007;
/* Function to count the number of
subsets with sum k using recursion */
private int findWaysUtil(int ind, int target, int[] arr) {
/* Base case: If the target sum
is 0, we found a valid subset */
if (target == 0)
return 1;
/* Base case: If we have considered all elements
and the target is still not 0, return 0 */
if (ind == 0)
return (arr[0] == target) ? 1 : 0;
// Exclude the current element
int notTaken = findWaysUtil(ind - 1, target, arr);
/* Include the current element if
it doesn't exceed the target */
int taken = 0;
if (arr[ind] <= target)
taken = findWaysUtil(ind - 1, target - arr[ind], arr);
/* Return the result. Also, take
modulo for the code to be accepted*/
return (notTaken + taken) % MODULO;
}
// Function to find out number of subsets with sum k
public int perfectSum(int[] arr, int K) {
int n = arr.length;
// Return the result
return findWaysUtil(n - 1, K, arr);
}
public static void main(String[] args) {
int[] arr = {1, 2, 2, 3};
int k = 3;
// Create an instance of Solution class
Solution sol = new Solution();
// Print the result
System.out.println("The number of subsets found are " + sol.perfectSum(arr, k));
}
}
MODULO = 10**9 + 7
class Solution:
""" Function to count the number of
subsets with sum k using recursion """
def findWaysUtil(self, ind, target, arr):
""" Base case: If the target sum
is 0, we found a valid subset """
if target == 0:
return 1
""" Base case: If we have considered all elements
and the target is still not 0, return 0 """
if ind == 0:
return 1 if arr[0] == target else 0
# Exclude the current element
notTaken = self.findWaysUtil(ind - 1, target, arr)
""" Include the current element if
it doesn't exceed the target"""
taken = 0
if arr[ind] <= target:
taken = self.findWaysUtil(ind - 1, target - arr[ind], arr)
""" Return the result. Also, take
modulo for the code to be accepted"""
return (notTaken + taken) % MODULO
# Function to find out number of subsets with sum k
def perfectSum(self, arr, K):
n = len(arr)
# Return the result
return self.findWaysUtil(n - 1, K, arr)
if __name__ == "__main__":
arr = [1, 2, 2, 3]
k = 3
#Create an instance of Solution class
sol = Solution()
#Print the result
print(f"The number of subsets found are {sol.perfectSum(arr, k)}")
const MODULO = 1e9 + 7;
class Solution {
/* Function to count the number of
subsets with sum k using recursion */
findWaysUtil(ind, target, arr) {
/* Base case: If the target sum
is 0, we found a valid subset */
if (target === 0)
return 1;
/* Base case: If we have considered all elements
and the target is still not 0, return 0 */
if (ind === 0)
return arr[0] === target ? 1 : 0;
// Exclude the current element
const notTaken = this.findWaysUtil(ind - 1, target, arr);
/* Include the current element if
it doesn't exceed the target */
let taken = 0;
if (arr[ind] <= target)
taken = this.findWaysUtil(ind - 1, target - arr[ind], arr);
/* Return the result. Also, take
modulo for the code to be accepted*/
return (notTaken + taken) % MODULO;
}
// Function to find out number of subsets with sum k
perfectSum(arr, K) {
const n = arr.length;
// Return the result
return this.findWaysUtil(n - 1, K, arr);
}
}
const arr = [1, 2, 2, 3];
const k = 3;
//Create an instance of Solution class
const sol = new Solution();
//Print the result
console.log(`The number of subsets found are ${sol.perfectSum(arr, k)}`);
If we draw the recursion tree, we will see that there are overlapping subproblems. Hence the DP approaches can be applied to the recursive solution.
The dp array stores the calculations of subproblems. Initialize dp array with -1, to indicate that no subproblem has been solved yet.
#include <bits/stdc++.h>
using namespace std;
class Solution{
int modulo = 1e9+7;
private:
/*Function to count the number of
subsets with sum k using memoization*/
int findWaysUtil(int ind, int target, vector<int>& arr, vector<vector<int>>& dp) {
/* Base case: If the target sum
is 0, we found a valid subset*/
if (target == 0)
return 1;
/* Base case: If we have considered all elements
and the target is still not 0, return 0*/
if (ind == 0)
return (arr[0] == target) ? 1 : 0;
/* If the result for this state
is already calculated, return it*/
if (dp[ind][target] != -1)
return dp[ind][target];
// Exclude the current element
int notTaken = findWaysUtil(ind - 1, target, arr, dp);
/* Include the current element if
it doesn't exceed the target*/
int taken = 0;
if (arr[ind] <= target)
taken = findWaysUtil(ind - 1, target - arr[ind], arr, dp);
/* Store the result in DP table and return
Also, take modulo for the code to be accepted*/
return dp[ind][target] = (notTaken + taken)%modulo;
}
public:
//Function to find out number of subsets with sum k
int perfectSum(vector<int>&arr, int K){
int n = arr.size();
//DP array to store the subproblems
vector<vector<int>> dp(n, vector<int>(K + 1, -1));
//Return the result
return findWaysUtil(n - 1, K, arr, dp);
}
};
int main() {
vector<int> arr = {1, 2, 2, 3};
int k = 3;
//Create an instance of Solution class
Solution sol;
//Print the result
cout << "The number of subsets found are " << sol.perfectSum(arr, k);
return 0;
}
import java.util.Arrays;
class Solution {
private static final int MODULO = 1000000007;
/* Function to count the number of
subsets with sum k using memoization */
private int findWaysUtil(int ind, int target, int[] arr, int[][] dp) {
/* Base case: If the target sum
is 0, we found a valid subset */
if (target == 0)
return 1;
/* Base case: If we have considered all elements
and the target is still not 0, return 0 */
if (ind == 0)
return (arr[0] == target) ? 1 : 0;
/* If the result for this state
is already calculated, return it */
if (dp[ind][target] != -1)
return dp[ind][target];
// Exclude the current element
int notTaken = findWaysUtil(ind - 1, target, arr, dp);
/* Include the current element if
it doesn't exceed the target */
int taken = 0;
if (arr[ind] <= target)
taken = findWaysUtil(ind - 1, target - arr[ind], arr, dp);
/* Store the result in DP table and return
Also, take modulo for the code to be accepted*/
return dp[ind][target] = (notTaken + taken) % MODULO;
}
// Function to find out number of subsets with sum k
public int perfectSum(int[] arr, int K) {
int n = arr.length;
// DP array to store the subproblems
int[][] dp = new int[n][K + 1];
for (int[] row : dp) {
Arrays.fill(row, -1);
}
// Return the result
return findWaysUtil(n - 1, K, arr, dp);
}
public static void main(String[] args) {
int[] arr = {1, 2, 2, 3};
int k = 3;
// Create an instance of Solution class
Solution sol = new Solution();
// Print the result
System.out.println("The number of subsets found are " + sol.perfectSum(arr, k));
}
}
MODULO = 10**9 + 7
class Solution:
""" Function to count the number of
subsets with sum k using memoization """
def findWaysUtil(self, ind, target, arr, dp):
""" Base case: If the target sum
is 0, we found a valid subset """
if target == 0:
return 1
""" Base case: If we have considered all elements
and the target is still not 0, return 0 """
if ind == 0:
return 1 if arr[0] == target else 0
""" If the result for this state
is already calculated, return it """
if dp[ind][target] != -1:
return dp[ind][target]
# Exclude the current element
notTaken = self.findWaysUtil(ind - 1, target, arr, dp)
""" Include the current element if
it doesn't exceed the target"""
taken = 0
if arr[ind] <= target:
taken = self.findWaysUtil(ind - 1, target - arr[ind], arr, dp)
"""Store the result in DP table and return
Also, take modulo for the code to be accepted"""
dp[ind][target] = (notTaken + taken) % MODULO
return dp[ind][target]
# Function to find out number of subsets with sum k
def perfectSum(self, arr, K):
n = len(arr)
# DP array to store the subproblems
dp = [[-1] * (K + 1) for _ in range(n)]
# Return the result
return self.findWaysUtil(n - 1, K, arr, dp)
if __name__ == "__main__":
arr = [1, 2, 2, 3]
k = 3
#Create an instance of Solution class
sol = Solution()
#Print the result
print(f"The number of subsets found are {sol.perfectSum(arr, k)}")
const MODULO = 1e9 + 7;
class Solution {
/* Function to count the number of
subsets with sum k using memoization */
findWaysUtil(ind, target, arr, dp) {
/* Base case: If the target sum
is 0, we found a valid subset */
if (target === 0)
return 1;
/* Base case: If we have considered all elements
and the target is still not 0, return 0 */
if (ind === 0)
return arr[0] === target ? 1 : 0;
/* If the result for this state
is already calculated, return it */
if (dp[ind][target] !== -1)
return dp[ind][target];
// Exclude the current element
const notTaken = this.findWaysUtil(ind - 1, target, arr, dp);
/* Include the current element if
it doesn't exceed the target */
let taken = 0;
if (arr[ind] <= target)
taken = this.findWaysUtil(ind - 1, target - arr[ind], arr, dp);
/* Store the result in DP table and return
Also, take modulo for the code to be accepted*/
dp[ind][target] = (notTaken + taken) % MODULO;
return dp[ind][target];
}
// Function to find out number of subsets with sum k
perfectSum(arr, K) {
const n = arr.length;
// DP array to store the subproblems
const dp = Array.from({ length: n }, () => Array(K + 1).fill(-1));
// Return the result
return this.findWaysUtil(n - 1, K, arr, dp);
}
}
const arr = [1, 2, 2, 3];
const k = 3;
//Create an instance of Solution class
const sol = new Solution();
//Print the result
console.log(`The number of subsets found are ${sol.perfectSum(arr, k)}`);
To convert a recursive code to tabulation code, we try to convert the recursive code to tabulation and here are the steps:
The first row dp[0][] indicates that only the first element of the array is considered, therefore for the target value equal to arr[0], only cell with that target will be true, so explicitly set dp[0][arr[0]] =1, (dp[0][arr[0]] means that we are considering the first element of the array with the target equal to the first element itself). Please note that it can happen that arr[0]>target, so we first check it: if(arr[0]<=target) then set dp[0][arr[0]] = 1
#include <bits/stdc++.h>
using namespace std;
class Solution{
int modulo = 1e9+7;
public:
//Function to find out number of subsets with sum k
int perfectSum(vector<int>&arr, int K){
int n = arr.size();
/* Create a 2D DP table with dimensions
n x k+1, initialized with zeros*/
vector<vector<int>> dp(n, vector<int>(K + 1, 0));
/* Base case: If the target sum is 0, there
is one valid subset (the empty subset)*/
for (int i = 0; i < n; i++) {
dp[i][0] = 1;
}
/* Initialize the first row based
on the first element of the array*/
if (arr[0] <= K) {
dp[0][arr[0]] = 1;
}
// Fill in the DP table using a bottom-up approach
for (int ind = 1; ind < n; ind++) {
for (int target = 1; target <= K; target++) {
// Exclude the current element
int notTaken = dp[ind - 1][target];
/* Include the current element
if it doesn't exceed the target*/
int taken = 0;
if (arr[ind] <= target) {
taken = (dp[ind - 1][target - arr[ind]]) % modulo;
}
/* Update the DP table and take
modulo for the code to be accepted*/
dp[ind][target] = (notTaken + taken)%modulo;
}
}
// The final result is in the last cell of table
return dp[n - 1][K];
}
};
int main() {
vector<int> arr = {1, 2, 2, 3};
int k = 3;
//Create an instance of Solution class
Solution sol;
//Print the result
cout << "The number of subsets found are " << sol.perfectSum(arr, k);
return 0;
}
import java.util.*;
class Solution {
private static final int MODULO = 1000000007;
// Function to find out number of subsets with sum k
public int perfectSum(int[] arr, int K) {
int n = arr.length;
/* Create a 2D DP table with dimensions
n x k+1, initialized with zeros */
int[][] dp = new int[n][K + 1];
/* Base case: If the target sum is 0, there
is one valid subset (the empty subset) */
for (int i = 0; i < n; i++) {
dp[i][0] = 1;
}
/* Initialize the first row based
on the first element of the array */
if (arr[0] <= K) {
dp[0][arr[0]] = 1;
}
// Fill in the DP table using a bottom-up approach
for (int ind = 1; ind < n; ind++) {
for (int target = 1; target <= K; target++) {
// Exclude the current element
int notTaken = dp[ind - 1][target];
/* Include the current element
if it doesn't exceed the target */
int taken = 0;
if (arr[ind] <= target) {
taken = dp[ind - 1][target - arr[ind]] % MODULO;
}
/* Update the DP table and take
modulo for the code to be accepted */
dp[ind][target] = (notTaken + taken) % MODULO;
}
}
// The final result is in the last cell of table
return dp[n - 1][K];
}
public static void main(String[] args) {
int[] arr = {1, 2, 2, 3};
int k = 3;
// Create an instance of Solution class
Solution sol = new Solution();
// Print the result
System.out.println("The number of subsets found are " + sol.perfectSum(arr, k));
}
}
MODULO = 10**9 + 7
class Solution:
# Function to find out number of subsets with sum k
def perfectSum(self, arr, K):
n = len(arr)
""" Create a 2D DP table with dimensions
n x k+1, initialized with zeros"""
dp = [[0] * (K + 1) for _ in range(n)]
""" Base case: If the target sum is 0, there
is one valid subset (the empty subset)"""
for i in range(n):
dp[i][0] = 1
""" Initialize the first row based
on the first element of the array"""
if arr[0] <= K:
dp[0][arr[0]] = 1
# Fill in the DP table using a bottom-up approach
for ind in range(1, n):
for target in range(1, K + 1):
# Exclude the current element
notTaken = dp[ind - 1][target]
""" Include the current element if
it doesn't exceed the target"""
taken = 0
if arr[ind] <= target:
taken = dp[ind - 1][target - arr[ind]] % MODULO
""" Update the DP table and take
modulo for the code to be accepted"""
dp[ind][target] = (notTaken + taken) % MODULO
# The final result is in the last cell of table
return dp[n - 1][K]
if __name__ == "__main__":
arr = [1, 2, 2, 3]
k = 3
#Create an instance of Solution class
sol = Solution()
#Print the answer
print(f"The number of subsets found are {sol.perfectSum(arr, k)}")
const MODULO = 1e9 + 7;
class Solution {
// Function to find out number of subsets with sum k
perfectSum(arr, K) {
const n = arr.length;
/* Create a 2D DP table with dimensions
n x k+1, initialized with zeros*/
const dp = Array.from({ length: n }, () => Array(K + 1).fill(0));
/* Base case: If the target sum is 0,
there is one valid subset (the empty subset)*/
for (let i = 0; i < n; i++) {
dp[i][0] = 1;
}
/* Initialize the first row based
on the first element of the array*/
if (arr[0] <= K) {
dp[0][arr[0]] = 1;
}
// Fill in the DP table using a bottom-up approach
for (let ind = 1; ind < n; ind++) {
for (let target = 1; target <= K; target++) {
// Exclude the current element
const notTaken = dp[ind - 1][target];
/* Include the current element
if it doesn't exceed the target*/
let taken = 0;
if (arr[ind] <= target) {
taken = dp[ind - 1][target - arr[ind]] % MODULO;
}
/* Update the DP table and take
modulo for the code to be accepted*/
dp[ind][target] = (notTaken + taken) % MODULO;
}
}
// The final result is in the last cell of table
return dp[n - 1][K];
}
}
const arr = [1, 2, 2, 3];
const k = 3;
//Create an instance of Solution class
const sol = new Solution();
//Print the result
console.log(`The number of subsets found are ${sol.perfectSum(arr, k)}`);
If we observe the relation, dp[ind][target] = dp[ind-1][target] + dp[ind-1][target-arr[ind]]. We find that to calculate a value of a cell of the dp array, we need only the previous row values (say prev). So, we don’t need to store an entire array. Hence we can space optimize it.
#include <bits/stdc++.h>
using namespace std;
class Solution{
int modulo = 1e9+7;
public:
//Function to find out number of subsets with sum k
int perfectSum(vector<int>&arr, int K){
int n = arr.size();
/* Initialize a vector 'prev' to represent
the previous row of the DP table*/
vector<int> prev(K + 1, 0);
/* Base case: If the target sum is 0,
there is one valid subset (the empty subset)*/
prev[0] = 1;
/* Initialize the first row based
on the first element of the array*/
if (arr[0] <= K) {
prev[arr[0]] = 1;
}
/* Fill in the DP table
using a bottom-up approach*/
for (int ind = 1; ind < n; ind++) {
/* Create a vector 'cur' to represent
the current row of the DP table*/
vector<int> cur(K + 1, 0);
cur[0] = 1;
for (int target = 1; target <= K; target++) {
// Exclude the current element
int notTaken = prev[target];
/* Include the current element
if it doesn't exceed the target*/
int taken = 0;
if (arr[ind] <= target) {
taken = prev[target - arr[ind]];
}
// Update the current row of the DP table
cur[target] = (notTaken + taken)%modulo;
}
// Set 'cur' as 'prev' for the next iteration
prev = cur;
}
/* The final result is in the
last cell of the 'prev' vector*/
return prev[K];
}
};
int main() {
vector<int> arr = {1, 2, 2, 3};
int k = 3;
//Create an instance of Solution class
Solution sol;
//Print the result
cout << "The number of subsets found are " << sol.perfectSum(arr, k);
return 0;
}
import java.util.*;
class Solution {
private static final int MODULO = 1000000007;
// Function to find out number of subsets with sum k
public int perfectSum(int[] arr, int K) {
int n = arr.length;
/* Initialize a vector 'prev' to represent
the previous row of the DP table */
int[] prev = new int[K + 1];
Arrays.fill(prev, 0);
/* Base case: If the target sum is 0,
there is one valid subset (the empty subset) */
prev[0] = 1;
/* Initialize the first row based
on the first element of the array */
if (arr[0] <= K) {
prev[arr[0]] = 1;
}
/* Fill in the DP table
using a bottom-up approach */
for (int ind = 1; ind < n; ind++) {
/* Create a vector 'cur' to represent
the current row of the DP table */
int[] cur = new int[K + 1];
Arrays.fill(cur, 0);
cur[0] = 1;
for (int target = 1; target <= K; target++) {
// Exclude the current element
int notTaken = prev[target];
/* Include the current element
if it doesn't exceed the target */
int taken = 0;
if (arr[ind] <= target) {
taken = prev[target - arr[ind]];
}
// Update the current row of the DP table
cur[target] = (notTaken + taken) % MODULO;
}
// Set 'cur' as 'prev' for the next iteration
prev = cur;
}
/* The final result is in the
last cell of the 'prev' vector */
return prev[K];
}
public static void main(String[] args) {
int[] arr = {1, 2, 2, 3};
int k = 3;
// Create an instance of Solution class
Solution sol = new Solution();
// Print the result
System.out.println("The number of subsets found are " + sol.perfectSum(arr, k));
}
}
MODULO = 10**9 + 7
class Solution:
# Function to find out number of subsets with sum k
def perfectSum(self, arr, K):
n = len(arr)
""" Initialize a vector 'prev' to represent
the previous row of the DP table"""
prev = [0] * (K + 1)
""" Base case: If the target sum is 0,
there is one valid subset (the empty subset)"""
prev[0] = 1
""" Initialize the first row based
on the first element of the array"""
if arr[0] <= K:
prev[arr[0]] = 1
""" Fill in the DP table
using a bottom-up approach"""
for ind in range(1, n):
""" Create a vector 'cur' to represent
the current row of the DP table"""
cur = [0] * (K + 1)
cur[0] = 1
for target in range(1, K + 1):
# Exclude the current element
notTaken = prev[target]
""" Include the current element
if it doesn't exceed the target"""
taken = 0
if arr[ind] <= target:
taken = prev[target - arr[ind]]
# Update the current row of the DP table
cur[target] = (notTaken + taken) % MODULO
# Set 'cur' as 'prev' for the next iteration
prev = cur
""" The final result is in the
last cell of the 'prev' vector"""
return prev[K]
if __name__ == "__main__":
arr = [1, 2, 2, 3]
k = 3
#Create an instance of Solution class
sol = Solution()
#Print the result
print(f"The number of subsets found are {sol.perfectSum(arr, k)}")
const MODULO = 1e9 + 7;
class Solution {
// Function to find out number of subsets with sum k
perfectSum(arr, K) {
const n = arr.length;
/* Initialize a vector 'prev' to represent
the previous row of the DP table*/
let prev = new Array(K + 1).fill(0);
/* Base case: If the target sum is 0,
there is one valid subset (the empty subset)*/
prev[0] = 1;
/* Initialize the first row based
on the first element of the array*/
if (arr[0] <= K) {
prev[arr[0]] = 1;
}
/* Fill in the DP table
using a bottom-up approach*/
for (let ind = 1; ind < n; ind++) {
/* Create a vector 'cur' to represent
the current row of the DP table*/
let cur = new Array(K + 1).fill(0);
cur[0] = 1;
for (let target = 1; target <= K; target++) {
// Exclude the current element
let notTaken = prev[target];
/* Include the current element
if it doesn't exceed the target*/
let taken = 0;
if (arr[ind] <= target) {
taken = prev[target - arr[ind]];
}
// Update the current row of the DP table
cur[target] = (notTaken + taken) % MODULO;
}
// Set 'cur' as 'prev' for the next iteration
prev = cur;
}
/* The final result is in the
last cell of the 'prev' vector*/
return prev[K];
}
}
const arr = [1, 2, 2, 3];
const k = 3;
//Create an instance of Solution class
const sol = new Solution();
//Print the result
console.log(`The number of subsets found are ${sol.perfectSum(arr, k)}`);
Q: Can a greedy approach work instead of DP?
A: No, because a greedy approach fails when elements must be selected in a specific order.
Q: How would you modify this problem to return the actual subsets instead of just counting them?
A: Maintain a backtracking path (dp[i][j] storing contributing elements) to reconstruct subsets.
Q: How does this problem relate to subset sum with multiplicity?
A: If elements can be used multiple times, modify DP as: dp[j]=dp[j]+dp[j−arr[i]]