Given an array arr[] of m distinct positive integers and an integer n, count the total number of ways to form n by adding the array elements. Repetition of elements is allowed and different arrangements are counted as separate ways.
Note: Since the answer can be very large, return it modulo 10^9 + 7.
Examples :
Input: arr[] = {1,5,6}, n = 7
Output: 6
Explanation: The different ways are: 1+1+1+1+1+1+1, 1+1+5, 1+5+1, 5+1+1, 1+6, 6+1Input: arr[] = {1,2,3}, n = 3
Output: 4
Explanation: The different ways are: 1+1+1, 1+2, 2+1, 3
Table of Content
[Naive Approach] Using Simple Recursion - O(m^n) Time and O(n) Space
The idea of this approach is to recursively try every array element for the current sum n. For each chosen element arr[i], reduce the remaining sum to n - arr[i] and recursively count the number of ways to form the remaining value.
Since different arrangements of same numbers are allowed, every possible ordering is explored. If the remaining sum becomes 0, it means one valid way is found, so return 1. The final answer is the sum of all possible recursive choices.
#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007
int countWays(vector<int>& arr, int n) {
// Base Case
if (n == 0)
return 1;
long ways = 0;
// Try every element
for (int i = 0; i < arr.size(); i++) {
if (n >= arr[i])
ways = (ways + countWays(arr, n - arr[i])) % mod;
}
return (int)ways;
}
int main() {
vector<int> arr = {1, 5, 6};
int n = 7;
cout << countWays(arr, n);
return 0;
}
class GFG {
static int mod = 1000000007;
public static int countWays(int[] arr, int n) {
// Base Case
if (n == 0)
return 1;
long ways = 0;
// Try every element
for (int i = 0; i < arr.length; i++) {
if (n >= arr[i])
ways = (ways + countWays(arr, n - arr[i])) % mod;
}
return (int) ways;
}
public static void main(String[] args) {
int[] arr = {1, 5, 6};
int n = 7;
System.out.println(countWays(arr, n));
}
}
mod = 1000000007
def countWays(arr, n):
# Base Case
if n == 0:
return 1
ways = 0
# Try every element
for i in range(len(arr)):
if n >= arr[i]:
ways = (ways + countWays(arr, n - arr[i])) % mod
return ways
if __name__ == "__main__":
arr = [1, 5, 6]
n = 7
print(countWays(arr, n))
using System;
class GFG
{
static int mod = 1000000007;
static int countWays(int[] arr, int n)
{
// Base Case
if (n == 0)
return 1;
long ways = 0;
// Try every element
for (int i = 0; i < arr.Length; i++)
{
if (n >= arr[i])
ways = (ways + countWays(arr, n - arr[i])) % mod;
}
return (int)ways;
}
static void Main()
{
int[] arr = {1, 5, 6};
int n = 7;
Console.WriteLine(countWays(arr, n));
}
}
const mod = 1000000007;
function countWays(arr, n) {
// Base Case
if (n === 0)
return 1;
let ways = 0;
// Try every element
for (let i = 0; i < arr.length; i++) {
if (n >= arr[i])
ways = (ways + countWays(arr, n - arr[i])) % mod;
}
return ways;
}
// Driver code
let arr = [1, 5, 6];
let n = 7;
console.log(countWays(arr, n));
Output
6
[Better Approach] Using Recursion + Memoization - O(n * m) Time and O(n) Space
The idea is to store the result for each value of n in a DP array. If the same value appears again, we directly return the stored result instead of recomputing it.
- Create a DP array dp[] of size n+ 1 and initialize all values with -1.
- If n == 0, return 1 (There is exactly one way to form sum 0: by selecting no elements).
- If dp[n] != -1, return dp[n] (already computed).
- Initialize ways = 0.
- Try every element arr[i]:
- If arr[i] <= n, recursively call for n - arr[i].
- Store the computed result in dp[n].
- Return dp[n] as the final answer.
#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007
// Function to count the total number of ways to form n
int solve(vector<int>& arr, int n, vector<int>& dp) {
// Base Case
if (n == 0)
return 1;
// Already computed
if (dp[n] != -1)
return dp[n];
long long ways = 0;
// Try every element
for (int i = 0; i < arr.size(); i++) {
if (n >= arr[i]) {
ways = (ways + solve(arr, n - arr[i], dp)) % mod;
}
}
return dp[n] = (int)ways;
}
int countWays(vector<int>& arr, int n) {
vector<int> dp(n + 1, -1);
return solve(arr, n, dp);
}
int main() {
vector<int> arr = {1, 5, 6};
int n = 7;
cout << countWays(arr, n);
return 0;
}
class GFG
{
static int mod = 1000000007;
// Function to count the total number of ways to form n
public static int solve(int[] arr, int n, int[] dp)
{
// Base Case
if (n == 0)
return 1;
// Already computed
if (dp[n] != -1)
return dp[n];
long ways = 0;
// Try every element
for (int i = 0; i < arr.length; i++)
{
if (n >= arr[i])
{
ways = (ways + solve(arr, n - arr[i], dp)) % mod;
}
}
return dp[n] = (int) ways;
}
public static int countWays(int[] arr, int n)
{
int[] dp = new int[n + 1];
for (int i = 0; i <= n; i++)
dp[i] = -1;
return solve(arr, n, dp);
}
public static void main(String[] args)
{
int[] arr = {1, 5, 6};
int n = 7;
System.out.println(countWays(arr, n));
}
}
mod = 1000000007
# Function to count the total number of ways to form n
def solve(arr, n, dp):
# Base Case
if n == 0:
return 1
# Already computed
if dp[n] != -1:
return dp[n]
ways = 0
# Try every element
for i in range(len(arr)):
if n >= arr[i]:
ways = (ways + solve(arr, n - arr[i], dp)) % mod
dp[n] = ways
return dp[n]
def countWays(arr, n):
dp = [-1] * (n + 1)
return solve(arr, n, dp)
if __name__ == "__main__":
arr = [1, 5, 6]
n = 7
print(countWays(arr, n))
using System;
class GFG
{
static int mod = 1000000007;
// Function to count the total number of ways to form n
static int solve(int[] arr, int n, int[] dp)
{
// Base Case
if (n == 0)
return 1;
// Already computed
if (dp[n] != -1)
return dp[n];
long ways = 0;
// Try every element
for (int i = 0; i < arr.Length; i++)
{
if (n >= arr[i])
{
ways = (ways + solve(arr, n - arr[i], dp)) % mod;
}
}
return dp[n] = (int)ways;
}
static int countWays(int[] arr, int n)
{
int[] dp = new int[n + 1];
for (int i = 0; i <= n; i++)
dp[i] = -1;
return solve(arr, n, dp);
}
static void Main()
{
int[] arr = { 1, 5, 6 };
int n = 7;
Console.WriteLine(countWays(arr, n));
}
}
const mod = 1000000007;
// Function to count the total number of ways to form n
function solve(arr, n, dp) {
// Base Case
if (n === 0)
return 1;
// Already computed
if (dp[n] !== -1)
return dp[n];
let ways = 0;
// Try every element
for (let i = 0; i < arr.length; i++) {
if (n >= arr[i]) {
ways = (ways + solve(arr, n - arr[i], dp)) % mod;
}
}
dp[n] = ways;
return dp[n];
}
function countWays(arr, n) {
let dp = new Array(n + 1).fill(-1);
return solve(arr, n, dp);
}
// Driver code
let arr = [1, 5, 6];
let n = 7;
console.log(countWays(arr, n));
Output
6
[Expected Approach] Using Bottom-Up DP - O(n * m) Time and O(n) Space
The idea is to create a DP array where each index i stores the number of ways to form sum i using the given array elements. Since repetitions and different arrangements are allowed, every element can be used multiple times.
- Create a DP array dp[] of size n + 1 and initialize all values to 0.
- Set dp[0] = 1 because there is one way to form sum 0 (choose nothing).
- Traverse from 1 to n.
- For each value i, iterate over all array elements: If arr[j] <= i, then add dp[i - arr[j]] to dp[i].
- Return dp[n] as the final answer.
Consider the array arr = {1, 5, 6} and n = 7.
Step 1: We create a DP array of size n + 1: dp = {0, 0, 0, 0, 0, 0, 0, 0}. First, we set dp[0] = 1 because there is exactly one way to form sum 0 (by selecting nothing), so the array becomes dp = {1, 0, 0, 0, 0, 0, 0, 0}.
Step 2: For each i from 1 to n:
- For each element arr[j]
- If arr[j] ≤ i, then: dp[i] += dp[i - arr[j]]
Step 3: Build DP table:
- i = 1 -> using 1 -> dp[1] = dp[0] = 1
- i = 2 -> using 1 -> dp[2] = dp[1] = 1
- i = 3 -> using 1 -> dp[3] = dp[2] = 1
- i = 4 -> using 1 -> dp[4] = dp[3] = 1
- i = 5 -> using 1 -> dp[4], using 5 -> dp[0], so dp[5] = 2
- i = 6 -> using 1 -> dp[5], using 5 -> dp[1], using 6 -> dp[0], so dp[6] = 4
- i = 7 -> using 1 -> dp[6], using 5 -> dp[2], using 6 -> dp[1], so dp[7] = 6
Finally, the DP array becomes: dp = {1, 1, 1, 1, 1, 2, 4, 6}. Therefore, the total number of ways to form n = 7 is 6.
using namespace std;
#define mod 1000000007
// Function to count the total
// number of ways to form n
int countWays(vector<int>& arr, int n) {
vector<int> dp(n + 1, 0);
// Base case: one way to form sum 0 (choose nothing)
dp[0] = 1;
// Build solution bottom-up
for (int i = 1; i <= n; i++) {
for (int j = 0; j < arr.size(); j++) {
if (i >= arr[j]) {
// Add ways of forming remaining sum
dp[i] = (dp[i] + dp[i - arr[j]]) % mod;
}
}
}
return dp[n];
}
int main() {
vector<int> arr = {1, 5, 6};
int n = 7;
cout << countWays(arr, n);
return 0;
}
class GFG {
static int mod = 1000000007;
// Function to count the total number of ways to form n
public static int countWays(int[] arr, int n) {
int[] dp = new int[n + 1];
// Base case: one way to form sum 0 (choose nothing)
dp[0] = 1;
// Build solution bottom-up
for (int i = 1; i <= n; i++) {
for (int j = 0; j < arr.length; j++) {
if (i >= arr[j]) {
// Add ways of forming remaining sum
dp[i] = (dp[i] + dp[i - arr[j]]) % mod;
}
}
}
return dp[n];
}
public static void main(String[] args) {
int[] arr = {1, 5, 6};
int n = 7;
System.out.println(countWays(arr, n));
}
}
mod = 1000000007
# Function to count the total number of ways to form n
def countWays(arr, n):
dp = [0] * (n + 1)
# Base case: one way to form sum 0 (choose nothing)
dp[0] = 1
# Build solution bottom-up
for i in range(1, n + 1):
for x in arr:
if i >= x:
# Add ways of forming remaining sum
dp[i] = (dp[i] + dp[i - x]) % mod
return dp[n]
arr = [1, 5, 6]
n = 7
print(countWays(arr, n))
using System;
class GFG {
static int mod = 1000000007;
// Function to count the total number of ways to form n
public static int countWays(int[] arr, int n) {
int[] dp = new int[n + 1];
// Base case: one way to form sum 0 (choose nothing)
dp[0] = 1;
// Build solution bottom-up
for (int i = 1; i <= n; i++) {
for (int j = 0; j < arr.Length; j++) {
if (i >= arr[j]) {
// Add ways of forming remaining sum
dp[i] = (dp[i] + dp[i - arr[j]]) % mod;
}
}
}
return dp[n];
}
static void Main() {
int[] arr = {1, 5, 6};
int n = 7;
Console.WriteLine(countWays(arr, n));
}
}
function countWays(arr, n) {
const mod = 1000000007;
let dp = new Array(n + 1).fill(0);
// Base case: one way to form sum 0 (choose nothing)
dp[0] = 1;
// Build solution bottom-up
for (let i = 1; i <= n; i++) {
for (let j = 0; j < arr.length; j++) {
if (i >= arr[j]) {
// Add ways of forming remaining sum
dp[i] = (dp[i] + dp[i - arr[j]]) % mod;
}
}
}
return dp[n];
}
// Driver code
let arr = [1, 5, 6];
let n = 7;
console.log(countWays(arr, n));
Output
6