Given an integer N, and an integer K, the task is to count the number of distinct ways to represent the number N as a sum of K unique primes.
Note: Distinct means, let N = 7 and K = 2, then the only way can be {2,5}, because {5,2} is same as {2,5}. So only 1 way.
Examples:Â
Input: N = 10, K = 2 Output: 1 Explanation: The only way is {3, 7} or {7, 3} Input: N = 100, K = 5 Output: 55
Approach: The problem can be solved using Dynamic Programming and Sieve of Eratosthenes.Â
- Let dp[i][j][sum] be our 3D DP array, which stores the number of distinct ways to form a sum using j number of primes where the last index of prime selected is i in the prime vector.Â
 - The prime numbers can be efficiently computed using Sieve of Eratosthenes. So, we can get a check of prime in O(1) time.Â
 - Recurrence:
We can either include this current prime to our sum, or we can exclude it.Â
dp[i][j][sum] = solve(i+1, j+1, sum+prime[i]) + solve(i+1, j, sum)
Below is the implementation of the above approach :Â
C++
// C++ program to count the Number // of distinct ways to represent // a number as K different primes #include <bits/stdc++.h> using namespace std; Â
// Prime vector vector< int > prime; Â
// Sieve array of prime bool isprime[1000]; Â
// DP array int dp[200][20][1000]; Â
void sieve() {     // Initialise all numbers     // as prime     memset (isprime, true ,         sizeof (isprime)); Â
    // Sieve of Eratosthenes.     for ( int i = 2; i * i <= 1000;         i++)     {         if (isprime[i])         {             for ( int j = i * i;                 j <= 1000; j += i)             {                 isprime[j] = false ;             }         }     }     // Push all the primes into     // prime vector     for ( int i = 2; i <= 1000; i++)     {         if (isprime[i])         {             prime.push_back(i);         }     } } Â
// Function to get the number of // distinct ways to get sum // as K different primes int CountWays( int i, int j, int sum, Â Â Â Â Â Â Â Â int n, int k) { Â
    // If index went out of prime     // array size or the sum became     // larger than n return 0     if (i > prime.size() || sum > n)     {         return 0;     } Â
    // If sum becomes equal to n and     // j becomes exactly equal to k.     // Return 1, else if j is still     // not equal to k, return 0     if (sum == n) {         if (j == k) {             return 1;         }         return 0;     } Â
    // If sum!=n and still j as     // exceeded, return 0     if (j == k)         return 0; Â
    // If that state is already     // calculated, return directly     // the ans     if (dp[i][j][sum])         return dp[i][j][sum]; Â
    int inc = 0, exc = 0;     // Include the current prime     inc = CountWays(i + 1, j + 1,                 sum + prime[i],                 n, k); Â
    // Exclude the current prime     exc = CountWays(i + 1, j, sum,                 n, k); Â
    // Return by memoizing the ans     return dp[i][j][sum] = inc + exc; } Â
// Driver code int main() { Â
    // Precompute primes by sieve     sieve(); Â
    int N = 100, K = 5;          cout << CountWays(0, 0, 0, N, K); } |
Java
// Java program to count the number // of distinct ways to represent // a number as K different primes import java.io.*; import java.util.*; Â
class GFG{ Â
// Prime vector static ArrayList<Integer> prime = new ArrayList<Integer>(); Â
// Sieve array of prime static boolean [] isprime = new boolean [ 1000 ]; Â
// DP array static int [][][] dp = new int [ 200 ][ 20 ][ 1000 ]; Â
static void sieve() {          // Initialise all numbers     // as prime     for ( int i = 0 ; i < 1000 ; i++)         isprime[i] = true ; Â
    // Sieve of Eratosthenes.     for ( int i = 2 ; i * i < 1000 ; i++)     {         if (isprime[i])         {             for ( int j = i * i;                     j < 1000 ; j += i)             {                 isprime[j] = false ;             }         }     }          // Push all the primes into     // prime vector     for ( int i = 2 ; i < 1000 ; i++)     {         if (isprime[i])         {             prime.add(i);         }     } } Â
// Function to get the number of // distinct ways to get sum // as K different primes static int CountWays( int i, int j, int sum,                      int n, int k) {          // If index went out of prime     // array size or the sum became     // larger than n return 0     if (i >= prime.size() - 1 || sum > n)     {         return 0 ;     } Â
    // If sum becomes equal to n and     // j becomes exactly equal to k.     // Return 1, else if j is still     // not equal to k, return 0     if (sum == n)     {         if (j == k)         {             return 1 ;         }         return 0 ;     } Â
    // If sum!=n and still j as     // exceeded, return 0     if (j == k)         return 0 ; Â
    // If that state is already     // calculated, return directly     // the ans     if (dp[i][j][sum] != 0 )         return dp[i][j][sum]; Â
    int inc = 0 , exc = 0 ;     // Include the current prime     inc = CountWays(i + 1 , j + 1 ,                   sum + prime.get(i),                   n, k); Â
    // Exclude the current prime     exc = CountWays(i + 1 , j, sum, n, k); Â
    // Return by memoizing the ans     return dp[i][j][sum] = inc + exc; } Â
// Driver code public static void main(String[] args) { Â
    // Precompute primes by sieve     sieve(); Â
    int N = 100 , K = 5 ; Â
    System.out.println(CountWays( 0 , 0 , 0 , N, K)); } } Â
// This code is contributed by akhilsaini |
Python3
# Python3 program to count the number # of distinct ways to represent # a number as K different primes Â
# Prime list prime = [] Â
# Sieve array of prime isprime = [ True ] * 1000 Â
# DP array dp = [[[ '0' for col in range ( 200 )] Â Â Â Â Â Â Â Â Â Â Â Â for col in range ( 20 )] Â Â Â Â Â Â Â Â Â Â Â Â for row in range ( 1000 )] Â
def sieve(): Â
    # Sieve of Eratosthenes.     for i in range ( 2 , 1000 ):                  if (isprime[i]):             for j in range (i * i, 1000 , i):                 isprime[j] = False Â
    # Push all the primes into     # prime vector     for i in range ( 2 , 1000 ):         if (isprime[i]):             prime.append(i) Â
# Function to get the number of # distinct ways to get sum # as K different primes def CountWays(i, j, sums, n, k): Â
    # If index went out of prime     # array size or the sum became     # larger than n return 0     if (i > = len (prime) or sums > n):         return 0 Â
    # If sum becomes equal to n and     # j becomes exactly equal to k.     # Return 1, else if j is still     # not equal to k, return 0     if (sums = = n):         if (j = = k):             return 1                      return 0 Â
    # If sum!=n and still j as     # exceeded, return 0     if j = = k:         return 0 Â
    # If that state is already     # calculated, return directly     # the ans     if dp[i][j][sums] = = 0 :         return dp[i][j][sums] Â
    inc = 0     exc = 0          # Include the current prime     inc = CountWays(i + 1 , j + 1 ,                  sums + prime[i],                  n, k) Â
    # Exclude the current prime     exc = CountWays(i + 1 , j, sums, n, k) Â
    # Return by memoizing the ans     dp[i][j][sums] = inc + exc     return dp[i][j][sums] Â
# Driver code if __name__ = = "__main__" :          # Precompute primes by sieve     sieve() Â
    N = 100     K = 5 Â
    print (CountWays( 0 , 0 , 0 , N, K)) Â
# This code is contributed by akhilsaini |
C#
// C# program to count the number // of distinct ways to represent // a number as K different primes using System; using System.Collections.Generic; Â
class GFG{ Â
// Prime vector static List< int > prime = new List< int >(); Â
// Sieve array of prime static bool [] isprime = new bool [1000]; Â
// DP array static int [, , ] dp = new int [200, 20, 1000]; Â
static void sieve() {          // Initialise all numbers     // as prime     for ( int i = 0; i < 1000; i++)         isprime[i] = true ; Â
    // Sieve of Eratosthenes.     for ( int i = 2; i * i < 1000; i++)     {         if (isprime[i])         {             for ( int j = i * i;                     j < 1000; j += i)             {                 isprime[j] = false ;             }         }     }          // Push all the primes into     // prime vector     for ( int i = 2; i < 1000; i++)     {         if (isprime[i])         {             prime.Add(i);         }     } } Â
// Function to get the number of // distinct ways to get sum // as K different primes static int CountWays( int i, int j, int sum,                      int n, int k) {          // If index went out of prime     // array size or the sum became     // larger than n return 0     if (i >= prime.Count - 1 || sum > n)     {         return 0;     } Â
    // If sum becomes equal to n and     // j becomes exactly equal to k.     // Return 1, else if j is still     // not equal to k, return 0     if (sum == n)     {         if (j == k)         {             return 1;         }         return 0;     } Â
    // If sum!=n and still j as     // exceeded, return 0     if (j == k)         return 0; Â
    // If that state is already     // calculated, return directly     // the ans     if (dp[i, j, sum] != 0)         return dp[i, j, sum]; Â
    int inc = 0, exc = 0;          // Include the current prime     inc = CountWays(i + 1, j + 1,                   sum + prime[i], n, k); Â
    // Exclude the current prime     exc = CountWays(i + 1, j, sum, n, k); Â
    // Return by memoizing the ans     return dp[i, j, sum] = inc + exc; } Â
// Driver code static public void Main() {          // Precompute primes by sieve     sieve(); Â
    int N = 100, K = 5; Â
    Console.WriteLine(CountWays(0, 0, 0, N, K)); } } Â
// This code is contributed by akhilsaini |
Javascript
<script> // Javascript program to count the Number // of distinct ways to represent // a number as K different primes Â
// Prime vector var prime = [];Â Â
// Sieve array of prime var isprime = Array(1000).fill( true ); Â
// DP array var dp = Array.from(Array(200), ()=>Array(20)); for ( var i =0; i<200; i++) Â Â Â Â Â Â Â Â for ( var j =0; j<20; j++) Â Â Â Â Â Â Â Â Â Â Â Â dp[i][j] = new Array(1000).fill(0); Â
function sieve() {     // Initialise all numbers     // as prime Â
    // Sieve of Eratosthenes.     for ( var i = 2; i * i <= 1000;         i++)     {         if (isprime[i])         {             for ( var j = i * i;                 j <= 1000; j += i)             {                 isprime[j] = false ;             }         }     }     // Push all the primes into     // prime vector     for ( var i = 2; i <= 1000; i++)     {         if (isprime[i])         {             prime.push(i);         }     } } Â
// Function to get the number of // distinct ways to get sum // as K different primes function CountWays(i, j, sum, n, k) { Â
    // If index went out of prime     // array size or the sum became     // larger than n return 0     if (i > prime.length || sum > n)     {         return 0;     } Â
    // If sum becomes equal to n and     // j becomes exactly equal to k.     // Return 1, else if j is still     // not equal to k, return 0     if (sum == n) {         if (j == k) {             return 1;         }         return 0;     } Â
    // If sum!=n and still j as     // exceeded, return 0     if (j == k)         return 0; Â
    // If that state is already     // calculated, return directly     // the ans     if (dp[i][j][sum])         return dp[i][j][sum]; Â
    var inc = 0, exc = 0;     // Include the current prime     inc = CountWays(i + 1, j + 1,                 sum + prime[i],                 n, k); Â
    // Exclude the current prime     exc = CountWays(i + 1, j, sum,                 n, k); Â
    // Return by memoizing the ans     return dp[i][j][sum] = inc + exc; } Â
// Driver code // Precompute primes by sieve sieve(); var N = 100, K = 5; document.write( CountWays(0, 0, 0, N, K)); Â
Â
</script> |
55
Â
Time Complexity: O(N*K).
Auxiliary Space: O(20*200*1000).
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!