Number of distinct ways to represent a number as sum of K unique primes
Last Updated :
08 Mar, 2022
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++
#include <bits/stdc++.h>
using namespace std;
vector< int > prime;
bool isprime[1000];
int dp[200][20][1000];
void sieve()
{
memset (isprime, true ,
sizeof (isprime));
for ( int i = 2; i * i <= 1000;
i++)
{
if (isprime[i])
{
for ( int j = i * i;
j <= 1000; j += i)
{
isprime[j] = false ;
}
}
}
for ( int i = 2; i <= 1000; i++)
{
if (isprime[i])
{
prime.push_back(i);
}
}
}
int CountWays( int i, int j, int sum,
int n, int k)
{
if (i > prime.size() || sum > n)
{
return 0;
}
if (sum == n) {
if (j == k) {
return 1;
}
return 0;
}
if (j == k)
return 0;
if (dp[i][j][sum])
return dp[i][j][sum];
int inc = 0, exc = 0;
inc = CountWays(i + 1, j + 1,
sum + prime[i],
n, k);
exc = CountWays(i + 1, j, sum,
n, k);
return dp[i][j][sum] = inc + exc;
}
int main()
{
sieve();
int N = 100, K = 5;
cout << CountWays(0, 0, 0, N, K);
}
|
Java
import java.io.*;
import java.util.*;
class GFG{
static ArrayList<Integer> prime = new ArrayList<Integer>();
static boolean [] isprime = new boolean [ 1000 ];
static int [][][] dp = new int [ 200 ][ 20 ][ 1000 ];
static void sieve()
{
for ( int i = 0 ; i < 1000 ; i++)
isprime[i] = true ;
for ( int i = 2 ; i * i < 1000 ; i++)
{
if (isprime[i])
{
for ( int j = i * i;
j < 1000 ; j += i)
{
isprime[j] = false ;
}
}
}
for ( int i = 2 ; i < 1000 ; i++)
{
if (isprime[i])
{
prime.add(i);
}
}
}
static int CountWays( int i, int j, int sum,
int n, int k)
{
if (i >= prime.size() - 1 || sum > n)
{
return 0 ;
}
if (sum == n)
{
if (j == k)
{
return 1 ;
}
return 0 ;
}
if (j == k)
return 0 ;
if (dp[i][j][sum] != 0 )
return dp[i][j][sum];
int inc = 0 , exc = 0 ;
inc = CountWays(i + 1 , j + 1 ,
sum + prime.get(i),
n, k);
exc = CountWays(i + 1 , j, sum, n, k);
return dp[i][j][sum] = inc + exc;
}
public static void main(String[] args)
{
sieve();
int N = 100 , K = 5 ;
System.out.println(CountWays( 0 , 0 , 0 , N, K));
}
}
|
Python3
prime = []
isprime = [ True ] * 1000
dp = [[[ '0' for col in range ( 200 )]
for col in range ( 20 )]
for row in range ( 1000 )]
def sieve():
for i in range ( 2 , 1000 ):
if (isprime[i]):
for j in range (i * i, 1000 , i):
isprime[j] = False
for i in range ( 2 , 1000 ):
if (isprime[i]):
prime.append(i)
def CountWays(i, j, sums, n, k):
if (i > = len (prime) or sums > n):
return 0
if (sums = = n):
if (j = = k):
return 1
return 0
if j = = k:
return 0
if dp[i][j][sums] = = 0 :
return dp[i][j][sums]
inc = 0
exc = 0
inc = CountWays(i + 1 , j + 1 ,
sums + prime[i],
n, k)
exc = CountWays(i + 1 , j, sums, n, k)
dp[i][j][sums] = inc + exc
return dp[i][j][sums]
if __name__ = = "__main__" :
sieve()
N = 100
K = 5
print (CountWays( 0 , 0 , 0 , N, K))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static List< int > prime = new List< int >();
static bool [] isprime = new bool [1000];
static int [, , ] dp = new int [200, 20, 1000];
static void sieve()
{
for ( int i = 0; i < 1000; i++)
isprime[i] = true ;
for ( int i = 2; i * i < 1000; i++)
{
if (isprime[i])
{
for ( int j = i * i;
j < 1000; j += i)
{
isprime[j] = false ;
}
}
}
for ( int i = 2; i < 1000; i++)
{
if (isprime[i])
{
prime.Add(i);
}
}
}
static int CountWays( int i, int j, int sum,
int n, int k)
{
if (i >= prime.Count - 1 || sum > n)
{
return 0;
}
if (sum == n)
{
if (j == k)
{
return 1;
}
return 0;
}
if (j == k)
return 0;
if (dp[i, j, sum] != 0)
return dp[i, j, sum];
int inc = 0, exc = 0;
inc = CountWays(i + 1, j + 1,
sum + prime[i], n, k);
exc = CountWays(i + 1, j, sum, n, k);
return dp[i, j, sum] = inc + exc;
}
static public void Main()
{
sieve();
int N = 100, K = 5;
Console.WriteLine(CountWays(0, 0, 0, N, K));
}
}
|
Javascript
<script>
var prime = [];
var isprime = Array(1000).fill( true );
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()
{
for ( var i = 2; i * i <= 1000;
i++)
{
if (isprime[i])
{
for ( var j = i * i;
j <= 1000; j += i)
{
isprime[j] = false ;
}
}
}
for ( var i = 2; i <= 1000; i++)
{
if (isprime[i])
{
prime.push(i);
}
}
}
function CountWays(i, j, sum, n, k)
{
if (i > prime.length || sum > n)
{
return 0;
}
if (sum == n) {
if (j == k) {
return 1;
}
return 0;
}
if (j == k)
return 0;
if (dp[i][j][sum])
return dp[i][j][sum];
var inc = 0, exc = 0;
inc = CountWays(i + 1, j + 1,
sum + prime[i],
n, k);
exc = CountWays(i + 1, j, sum,
n, k);
return dp[i][j][sum] = inc + exc;
}
sieve();
var N = 100, K = 5;
document.write( CountWays(0, 0, 0, N, K));
</script>
|
Time Complexity: O(N*K).
Auxiliary Space: O(20*200*1000).
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...