Open In App

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

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

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++ 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 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 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# 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




<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).


Article Tags :