📌  相关文章
📜  将数字表示为K个唯一质数之和的不同方式的数量

📅  最后修改于: 2021-05-14 08:33:38             🧑  作者: Mango

给定一个整数N和一个整数K ,任务是计算将N表示为K个唯一素数之和的不同方式的数量。
注意:不同的意思是,让N = 7并且K = 2,则唯一的方法可以是{2,5},因为{5,2}与{2,5}相同。所以只有一种方法。

例子:

Input: N = 10, K = 2
Output: 1
Explanation:
The only way is {3, 7} or {7, 3}

Input: N = 100, K = 5
Output: 55

方法:可以使用动态编程和Eratosthenes筛子解决问题。

  • dp [i] [j] [sum]为我们的3D DP数组,该数组存储使用j个素数(其中素数的最后一个索引为i的i)形成求和不同方式的数目。
  • 质数可以使用Eratosthenes的Sieve进行有效地计算。因此,我们可以检查O(1)时间中的质数。
  • 复发:

下面是上述方法的实现:

C++
// C++ program to count the Number
// of distinct ways to represent
// a number as K different primes
#include 
using namespace std;
 
// Prime vector
vector 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 prime = new ArrayList();
 
// 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 prime = new List();
 
// 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


输出:
55