Skip to content
Related Articles

Related Articles

Improve Article

Number of ways to write N as a sum of K non-negative integers

  • Difficulty Level : Hard
  • Last Updated : 12 Jul, 2021
Geek Week

Given two positive integers N and K, the task is to count the number of ways to write N as a sum of K non-negative integers.

Examples: 

Input: N = 2, K = 3 
Output:
Explanation: 
The total ways in which 2 can be split into K non-negative integers are: 
1. (0, 0, 2) 
2. (0, 2, 0) 
3. (2, 0, 0) 
4. (0, 1, 1) 
5. (1, 0, 1) 
6. (1, 1, 0)

Input: N = 3, K = 2 
Output:
Explanation: 
The total ways in which can be split 3 into 2 non-negative integers are: 
1. (0, 3) 
2. (3, 0) 
3. (1, 2) 
4. (2, 1) 

Approach: This problem can be solved using Dynamic Programming. Below are the steps:  



  1. Initialize a 2D array as dp[K+1][N+1] where rows correspond to the number of the element we pick and columns correspond to the corresponding sum.
  2. Start filling the first row and column with taking sum as K in the above table dp[][].
  3. Suppose we reach at ith row and jth column, i.e i elements we can pick and we need to get sum j. To calculate the number of ways till dp[i][j] choose first (i – 1) elements and next (j – x) where x is the sum of first (i – 1) elements.
  4. Repeat the above steps to fill the dp[][] array.
  5. The value dp[n][m] will give the required result.

Below is the implementation of the above approach: 

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to count the number of ways
// to write N as sum of k non-negative
// integers
int countWays(int n, int m)
{
 
    // Initialise dp[][] array
    int dp[m + 1][n + 1];
 
    // Only 1 way to choose the value
    // with sum K
    for (int i = 0; i <= n; i++) {
        dp[1][i] = 1;
    }
 
    // Initialise sum
    int sum;
 
    for (int i = 2; i <= m; i++) {
        for (int j = 0; j <= n; j++) {
            sum = 0;
 
            // Count the ways from previous
            // states
            for (int k = 0; k <= j; k++) {
                sum += dp[i - 1][k];
            }
 
            // Update the sum
            dp[i][j] = sum;
        }
    }
 
    // Return the final count of ways
    return dp[m][n];
}
 
// Driver Code
int main()
{
    int N = 2, K = 3;
 
    // Function call
    cout << countWays(N, K);
    return 0;
}

Java




// Java program for the above approach
import java.util.*;
class GFG{
 
// Function to count the number of ways
// to write N as sum of k non-negative
// integers
static int countWays(int n, int m)
{
 
    // Initialise dp[][] array
    int [][]dp = new int[m + 1][n + 1];
 
    // Only 1 way to choose the value
    // with sum K
    for(int i = 0; i <= n; i++)
    {
       dp[1][i] = 1;
    }
 
    // Initialise sum
    int sum;
 
    for(int i = 2; i <= m; i++)
    {
       for(int j = 0; j <= n; j++)
       {
          sum = 0;
           
          // Count the ways from previous
          // states
          for(int k = 0; k <= j; k++)
          {
             sum += dp[i - 1][k];
          }
           
          // Update the sum
          dp[i][j] = sum;
       }
    }
 
    // Return the final count of ways
    return dp[m][n];
}
 
// Driver Code
public static void main(String[] args)
{
    int N = 2, K = 3;
 
    // Function call
    System.out.print(countWays(N, K));
}
}
 
// This code is contributed by gauravrajput1

Python3




# Python3 program for the above approach
 
# Function to count the number of ways
# to write N as sum of k non-negative
# integers
def countWays(n, m):
 
    # Initialise dp[][] array
    dp = [[ 0 for i in range(n + 1)]
              for i in range(m + 1)]
               
    # Only 1 way to choose the value
    # with sum K
    for i in range(n + 1):
        dp[1][i] = 1
 
    # Initialise sum
    sum = 0
 
    for i in range(2, m + 1):
        for j in range(n + 1):
            sum = 0
 
            # Count the ways from previous
            # states
            for k in range(j + 1):
                sum += dp[i - 1][k]
 
            # Update the sum
            dp[i][j] = sum
 
    # Return the final count of ways
    return dp[m][n]
 
# Driver Code
if __name__ == '__main__':
    N = 2
    K = 3
 
    # Function call
    print(countWays(N, K))
 
# This code is contributed by Mohit Kumar

C#




// C# program for the above approach
using System;
 
class GFG{
 
// Function to count the number of ways
// to write N as sum of k non-negative
// integers
static int countWays(int n, int m)
{
 
    // Initialise [,]dp array
    int [,]dp = new int[m + 1, n + 1];
 
    // Only 1 way to choose the value
    // with sum K
    for(int i = 0; i <= n; i++)
    {
       dp[1, i] = 1;
    }
 
    // Initialise sum
    int sum;
 
    for(int i = 2; i <= m; i++)
    {
       for(int j = 0; j <= n; j++)
       {
          sum = 0;
           
          // Count the ways from previous
          // states
          for(int k = 0; k <= j; k++)
          {
             sum += dp[i - 1, k];
          }
           
          // Update the sum
          dp[i, j] = sum;
       }
    }
 
    // Return the readonly count of ways
    return dp[m, n];
}
 
// Driver Code
public static void Main(String[] args)
{
    int N = 2, K = 3;
 
    // Function call
    Console.Write(countWays(N, K));
}
}
 
// This code is contributed by gauravrajput1

Javascript




<script>
 
// Javascript program for the above approach
 
// Function to count the number of ways
// to write N as sum of k non-negative
// integers
function countWays(n, m)
{
 
    // Initialise dp[][] array
    var dp = Array.from(Array(m+1), ()=>Array(n+1));
 
    // Only 1 way to choose the value
    // with sum K
    for (var i = 0; i <= n; i++) {
        dp[1][i] = 1;
    }
 
    // Initialise sum
    var sum;
 
    for (var i = 2; i <= m; i++) {
        for (var j = 0; j <= n; j++) {
            sum = 0;
 
            // Count the ways from previous
            // states
            for (var k = 0; k <= j; k++) {
                sum += dp[i - 1][k];
            }
 
            // Update the sum
            dp[i][j] = sum;
        }
    }
 
    // Return the final count of ways
    return dp[m][n];
}
 
// Driver Code
var N = 2, K = 3;
// Function call
document.write( countWays(N, K));
 
 
</script>
Output: 
6

 

Time Complexity: O(K*N2
Auxiliary Space Complexity: O(N*K) 
 

Optimized Approach: The idea of calculating the sum and then storing the count increases the time complexity. We can decrease it by storing the sum in the above dp[][] table.
Below is the implementation of the above approach: 

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to count the number of ways
// to write N as sum of k non-negative
// integers
int countWays(int n, int m)
{
    // Initialise dp[][] array
    int dp[m + 1][n + 1];
 
    // Fill the dp[][] with sum = m
    for (int i = 0; i <= n; i++) {
        dp[1][i] = 1;
        if (i != 0) {
            dp[1][i] += dp[1][i - 1];
        }
    }
 
    // Iterate the dp[][] to fill the
    // dp[][] array
    for (int i = 2; i <= m; i++) {
        for (int j = 0; j <= n; j++) {
 
            // Condition for first column
            if (j == 0) {
                dp[i][j] = dp[i - 1][j];
            }
 
            // Else fill the dp[][] with
            // sum till (i, j)
            else {
                dp[i][j] = dp[i - 1][j];
 
                // If reach the end, then
                // return the value
                if (i == m && j == n) {
                    return dp[i][j];
                }
 
                // Update at current index
                dp[i][j] += dp[i][j - 1];
            }
        }
    }
}
 
// Driver Code
int main()
{
    int N = 2, K = 3;
 
    // Function call
    cout << countWays(N, K);
    return 0;
}

Java




// Java program for the above approach
import java.util.*;
class GFG{
 
// Function to count the number of ways
// to write N as sum of k non-negative
// integers
static int countWays(int n, int m)
{
    // Initialise dp[][] array
    int [][]dp = new int[m + 1][n + 1];
 
    // Fill the dp[][] with sum = m
    for (int i = 0; i <= n; i++)
    {
        dp[1][i] = 1;
        if (i != 0)
        {
            dp[1][i] += dp[1][i - 1];
        }
    }
 
    // Iterate the dp[][] to fill the
    // dp[][] array
    for (int i = 2; i <= m; i++)
    {
        for (int j = 0; j <= n; j++)
        {
 
            // Condition for first column
            if (j == 0)
            {
                dp[i][j] = dp[i - 1][j];
            }
 
            // Else fill the dp[][] with
            // sum till (i, j)
            else
            {
                dp[i][j] = dp[i - 1][j];
 
                // If reach the end, then
                // return the value
                if (i == m && j == n)
                {
                    return dp[i][j];
                }
 
                // Update at current index
                dp[i][j] += dp[i][j - 1];
            }
        }
    }
    return Integer.MIN_VALUE;
}
 
// Driver Code
public static void main(String[] args)
{
    int N = 2, K = 3;
 
    // Function call
    System.out.print(countWays(N, K));
}
}
 
// This code is contributed by sapnasingh4991

Python3




# Python3 program for the above approach
 
# Function to count the number of ways
# to write N as sum of k non-negative
# integers
def countWays(n, m):
     
    # Initialise dp[][] array
    dp = [[0 for i in range(n + 1)]
             for j in range(m + 1)]
     
    # Fill the dp[][] with sum = m
    for i in range(n + 1):
        dp[1][i] = 1
        if (i != 0):
            dp[1][i] += dp[1][i - 1]
     
    # Iterate the dp[][] to fill the
    # dp[][] array
    for i in range(2, m + 1):
        for j in range(n + 1):
             
            # Condition for first column
            if (j == 0):
                dp[i][j] = dp[i - 1][j]
             
            # Else fill the dp[][] with
            # sum till (i, j)
            else:
                dp[i][j] = dp[i - 1][j]
                 
                # If reach the end, then
                # return the value
                if (i == m and j == n):
                    return dp[i][j]
                 
                # Update at current index
                dp[i][j] += dp[i][j - 1]
                 
# Driver Code
N = 2
K = 3
 
# Function call
print(countWays(N, K))
 
# This code is contributed by ShubhamCoder

C#




// C# program for the above approach
using System;
class GFG{
 
// Function to count the number of ways
// to write N as sum of k non-negative
// integers
static int countWays(int n, int m)
{
    // Initialise dp[][] array
    int [,]dp = new int[m + 1, n + 1];
 
    // Fill the dp[][] with sum = m
    for (int i = 0; i <= n; i++)
    {
        dp[1, i] = 1;
        if (i != 0)
        {
            dp[1, i] += dp[1, i - 1];
        }
    }
 
    // Iterate the dp[][] to fill the
    // dp[][] array
    for (int i = 2; i <= m; i++)
    {
        for (int j = 0; j <= n; j++)
        {
 
            // Condition for first column
            if (j == 0)
            {
                dp[i, j] = dp[i - 1, j];
            }
 
            // Else fill the dp[][] with
            // sum till (i, j)
            else
            {
                dp[i, j] = dp[i - 1, j];
 
                // If reach the end, then
                // return the value
                if (i == m && j == n)
                {
                    return dp[i, j];
                }
 
                // Update at current index
                dp[i, j] += dp[i, j - 1];
            }
        }
    }
    return Int32.MinValue;
}
 
// Driver Code
public static void Main()
{
    int N = 2, K = 3;
 
    // Function call
    Console.Write(countWays(N, K));
}
}
 
// This code is contributed by Code_Mech

Javascript




<script>
 
// JavaScript program for the above approach
 
// Function to count the number of ways
// to write N as sum of k non-negative
// integers
function countWays(n,m)
{
    // Initialise dp[][] array
    let dp = new Array(m + 1);
    for(let i=0;i<m+1;i++)
    {
        dp[i]=new Array(n+1);
        for(let j=0;j<n+1;j++)
            dp[i][j]=0;
    }
  
    // Fill the dp[][] with sum = m
    for (let i = 0; i <= n; i++)
    {
        dp[1][i] = 1;
        if (i != 0)
        {
            dp[1][i] += dp[1][i - 1];
        }
    }
  
    // Iterate the dp[][] to fill the
    // dp[][] array
    for (let i = 2; i <= m; i++)
    {
        for (let j = 0; j <= n; j++)
        {
  
            // Condition for first column
            if (j == 0)
            {
                dp[i][j] = dp[i - 1][j];
            }
  
            // Else fill the dp[][] with
            // sum till (i, j)
            else
            {
                dp[i][j] = dp[i - 1][j];
  
                // If reach the end, then
                // return the value
                if (i == m && j == n)
                {
                    return dp[i][j];
                }
  
                // Update at current index
                dp[i][j] += dp[i][j - 1];
            }
        }
    }
    return Number.MIN_VALUE;
}
 
// Driver Code
let N = 2, K = 3;
 
// Function call
document.write(countWays(N, K));
 
 
// This code is contributed by patel2127
 
</script>
Output: 
6

 

Time Complexity: O(K*N) 
Auxiliary Space Complexity: O(N*K) 
 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up
Recommended Articles
Page :