Open In App

Number of distinct ways to represent a number as sum of K unique primes

Last Updated : 08 Mar, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

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>


Output: 

55

 

Time Complexity: O(N*K).

Auxiliary Space: O(20*200*1000).



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads