Given two integers n and k, find the total number of ways to represent n as the sum of positive integers in the range [1, k], where each integer can be used multiple times.
Examples:
Input: n = 8, k = 2
Output: 5
Explanation: Possible ways are: {1,1,1,1,1,1,1,1}, {2,1,1,1,1,1,1}, {2,2,1,1,1,1}, {2,2,2,1,1} and {2,2,2,2}.Input: n = 2, k = 2
Output: 2
Explanation: Possible ways are: {1,1} and {2}.
Table of Content
[Naive Approach] Recursive Solution - O(2^(n + k)) Time and O(n) Space
The idea is to explore all possible combinations by making two choices for each number k: either include it in the sum or exclude it.
If we include k, we reduce the remaining sum n by k.
If we exclude k, we reduce the range by decreasing k.
using namespace std;
// Function that return Ways to sum to N using
// Natural Numbers up to K with repetitions allowed
int NumberOfways(int n, int k)
{
// Base case
if (n == 0)
return 1;
if (n < 0 || k <= 0)
return 0;
// including and not including K in sum
return NumberOfways(n - k, k) + NumberOfways(n, k - 1);
}
int main()
{
int n = 8;
int k = 2;
// function call
cout << NumberOfways(n, k) << endl;
return 0;
}
class GFG {
// Function that return Ways to sum to N using
// Natural Numbers up to K with repetitions allowed
public static int NumberOfways(int n, int k)
{
// Base case
if (n == 0)
return 1;
if (n < 0 || k <= 0)
return 0;
// including and not including k in sum
return NumberOfways(n - k, k)
+ NumberOfways(n, k - 1);
}
public static void main(String[] args)
{
int n = 8;
int k = 2;
// function call
System.out.println(NumberOfways(n, k));
}
}
# Function that returns the number of ways to sum
# to N using natural numbers up to K with repetitions allowed
def number_of_ways(n, k):
# Base case
if n == 0:
return 1
if n < 0 or k <= 0:
return 0
# Including and not including K in sum
return number_of_ways(n - k, k) + number_of_ways(n, k - 1)
if __name__ == '__main__':
n = 8
k = 2
# Function call
print(number_of_ways(n, k))
using System;
class GFG {
// Function that return Ways to sum to N using
// Natural Numbers up to K with repetitions allowed
static int NumberOfWays(int n, int k)
{
// Base case
if (n == 0)
return 1;
if (n < 0 || k <= 0)
return 0;
// including and not including K in sum
return NumberOfWays(n - k, k)
+ NumberOfWays(n, k - 1);
}
static void Main()
{
int n = 8;
int k = 2;
// function call
Console.WriteLine(NumberOfWays(n, k));
}
}
// Function that return Ways to sum to N using
// Natural Numbers up to K with repetitions allowed
function numberOfWays(n, k)
{
// Base case
if (n == 0)
return 1;
if (n < 0 || k <= 0)
return 0;
// including and not including K in sum
return numberOfWays(n - k, k) + numberOfWays(n, k - 1);
}
// Driver code
let n = 8;
let k = 2;
// function call
console.log(numberOfWays(n, k));
Output
5
[Expected Approach] Dynamic Programming - O(n * k) Time and O(n) Space
The Recursive approach has Overlapping Subproblems and an Optimal Substructure. To avoid recomputation, we use Dynamic Programming. We create an array dp where dp[i] stores the number of ways to form sum i. For each number from 1 to k, we update all possible sums by adding previously computed results.
Steps:
- Create an array dp[0..n], where dp[i] represents the number of ways to sum to i using numbers from 1 to k.
- Initialize dp[0] = 1 because there is exactly one way to sum to 0, which is using no numbers.
- Loop over numbers i from 1 to k, representing the numbers you can use in sums.
- For each number i, loop over j from 1 to n.
- If j >= i, update dp[j] = dp[j] + dp[j - i](all possible target sums).
- After completing all loops, dp[n] gives the total number of ways to sum to n.
#include <vector>
using namespace std;
// Function to find the total number of ways
// to represent n as the sum of numbers from 1 to k
int NumberOfways(int n, int k)
{
// Create a dp array where dp[i] stores
// the number of ways to make sum i
vector<int> dp(n + 1, 0);
// There is 1 way to make sum 0 (use no numbers)
dp[0] = 1;
// Loop through all numbers from 1 to k
for (int i = 1; i <= k; i++)
{
// Update dp array for all sums from i to n
for (int j = i; j <= n; j++)
{
dp[j] += dp[j - i];
}
}
// dp[n] now contains the total number of ways to make sum n
return dp[n];
}
int main()
{
int n = 8;
int k = 2;
cout << NumberOfways(n, k) << endl;
}
class GFG {
// Function to find the total number of ways
// to represent n as the sum of numbers from 1 to k
public static int NumberOfways(int n, int k)
{
// Create a dp array where dp[i] stores
// the number of ways to make sum i
int[] dp = new int[n + 1];
// There is 1 way to make sum 0 (use no numbers)
dp[0] = 1;
// Loop through all numbers from 1 to k
for (int i = 1; i <= k; i++) {
// Update dp array for all sums from i to n
for (int j = i; j <= n; j++) {
dp[j]
+= dp[j
- i]; // Add ways to make (j - i)
}
}
// dp[n] now contains the total number of ways to
// make sum n
return dp[n];
}
public static void main(String[] args)
{
int n = 8;
int k = 2;
System.out.println(NumberOfways(n, k));
}
}
# Function to find the total number of ways
# to represent n as the sum of numbers from 1 to k
def NumberOfways(n, k):
# Create a dp list where dp[i] stores
# the number of ways to make sum i
dp = [0] * (n + 1)
# There is 1 way to make sum 0 (use no numbers)
dp[0] = 1
# Loop through all numbers from 1 to k
for i in range(1, k + 1):
# Update dp list for all sums from i to n
for j in range(i, n + 1):
dp[j] += dp[j - i]
# dp[n] now contains the total number of ways to make sum n
return dp[n]
if __name__ == "__main__":
n = 8
k = 2
print(NumberOfways(n, k))
using System;
class GFG {
// Function to find the total number of ways
// to represent n as the sum of numbers from 1 to k
static int NumberOfways(int n, int k)
{
// Create a dp array where dp[i] stores
// the number of ways to make sum i
int[] dp = new int[n + 1];
// There is 1 way to make sum 0 (use no numbers)
dp[0] = 1;
// Loop through all numbers from 1 to k
for (int i = 1; i <= k; i++) {
// Update dp array for all sums from i to n
for (int j = i; j <= n; j++) {
dp[j] += dp[j - i];
}
}
// dp[n] now contains the total number of ways to
// make sum n
return dp[n];
}
static void Main()
{
int n = 8;
int k = 2;
Console.WriteLine(NumberOfways(n, k));
}
}
// Function to find the total number of ways
// to represent n as the sum of numbers from 1 to k
function NumberOfways(n, k)
{
// Create a dp array where dp[i] stores
// the number of ways to make sum i
let dp = new Array(n + 1).fill(0);
// There is 1 way to make sum 0 (use no numbers)
dp[0] = 1;
// Loop through all numbers from 1 to k
for (let i = 1; i <= k; i++) {
// Update dp array for all sums from i to n
for (let j = i; j <= n; j++) {
dp[j] += dp[j - i];
}
}
// dp[n] now contains the total number of ways to make
// sum n
return dp[n];
}
// driver code
let n = 8;
let k = 2;
console.log(NumberOfways(n, k));
Output
5