📌  相关文章
📜  包含所有个位数素数的 N 位数字的计数

📅  最后修改于: 2021-09-17 06:43:55             🧑  作者: Mango

给定一个正整数N ,任务是计算包含所有个位数素数的N位数字的数量。

例子:

朴素方法:解决给定问题的最简单方法是生成所有可能的N位数字,并计算那些包含所有单数素数的数字。检查所有数字后,打印计数值作为结果的总数字计数。

时间复杂度: O(N *10 N )
辅助空间: O(1)

高效方法:上述方法也可以通过使用动态规划进行优化,因为它具有重叠的子问题和最优子结构。子问题可以利用记忆化被存储在DP [] []表,其中DP [指数]索引[掩模]存储的答案直到结束,其中掩模被用来存储包括至今不同的素数的计数位置。请按照以下步骤解决问题:

  • 初始化一个全局多维数组dp[100][1<<4] ,所有值都为-1 ,用于存储每次递归调用的结果。
  • 使用 HashMap 以升序索引所有个位数素数
  • 通过执行以下步骤定义递归函数,例如countOfNumbers(index, mask, N)
    • 如果索引的值等于(N + 1),
      • 通过查找掩码中的设置位计数来计算包含的不同个位数素数的数量
      • 如果计数等于4 ,则返回1作为有效的N位数字已形成。
      • 否则返回0
    • 如果已经计算了状态dp[index][mask]的结果,则返回此值dp[index][mask]
    • 如果当前索引1 ,则可以放置[1-9] 中的任何数字,如果N = 1 ,则也可以放置0
    • 对于所有其他索引,可以放置[0-9] 中的任何数字。
    • 如果当前放置的数字是质数,则在位掩码中将质数的索引设置为1
    • 进行有效放置后,递归调用(index + 1)countOfNumbers函数。
    • 返回所有可能的有效数字位置的总和作为答案。
  • 打印函数countOfNumbers(1, 0, N)返回的值作为结果。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Stores the dp-states
int dp[100][1 << 4];
 
// Stores the index of prime numbers
map primeIndex;
 
int countOfNumbers(int index, int mask, int N)
{
    // If index = N+1
    if (index == N + 1) {
 
        // Find count of distinct
        // prime numbers by counting
        // number of set bits.
        int countOfPrimes = __builtin_popcount(mask);
 
        // If count of distinct
        // prime numbers is equal to 4
        // return 1.
        if (countOfPrimes == 4) {
            return 1;
        }
        return 0;
    }
 
    int& val = dp[index][mask];
 
    // If the state has
    // already been computed
    if (val != -1) {
        return val;
    }
 
    val = 0;
 
    // If current position is 1,
    // then any digit from [1-9] can be placed.
    // If N = 1, 0 can be also placed.
    if (index == 1) {
        for (int digit = (N == 1 ? 0 : 1); digit <= 9;
             ++digit) {
 
            // If the digit is a prime number,
            // set the index of the
            // digit to 1 in the bitmask.
            if (primeIndex.find(digit)
                != primeIndex.end()) {
                val += countOfNumbers(
                    index + 1,
                    mask | (1 << primeIndex[digit]), N);
            }
 
            else {
                val += countOfNumbers(index + 1, mask, N);
            }
        }
    }
 
    // For remaining positions,
    // any digit from [0-9] can be placed
    else {
        for (int digit = 0; digit <= 9; ++digit) {
 
            // If the digit is a prime number,
            // set the index of the
            // digit to 1 in the bitmask.
            if (primeIndex.find(digit)
                != primeIndex.end()) {
                val += countOfNumbers(
                    index + 1,
                    mask | (1 << primeIndex[digit]), N);
            }
 
            else {
                val += countOfNumbers(index + 1, mask, N);
            }
        }
    }
 
    // Return the answer.
    return val;
}
 
// Driver Code
int main()
{
    // Initializing dp array with -1.
    memset(dp, -1, sizeof dp);
 
    // Indexing prime numbers in
    // ascending order
    primeIndex[2] = 0;
    primeIndex[3] = 1;
    primeIndex[5] = 2;
    primeIndex[7] = 3;
 
    // Given Input
    int N = 4;
 
    // Function call.
    cout << countOfNumbers(1, 0, N);
 
    return 0;
}


Java
// Java program for the above approach
import java.io.*;
import java.util.*;
 
class GFG{
 
public static int[][] dp = new int[100][(1 << 4)];
 
// Stores the index of prime numbers
public static HashMap primeIndex = new HashMap<>();
 
public static int countSetBits(int n)
{
    int count = 0;
     
    while (n > 0)
    {
        count += n & 1;
        n >>= 1;
    }
    return count;
}
 
public static int countOfNumbers(int index, int mask,
                                 int N)
{
     
    // If index = N+1
    if (index == N + 1)
    {
         
        // Find count of distinct
        // prime numbers by counting
        // number of set bits.
        int countOfPrimes = countSetBits(mask);
 
        // If count of distinct
        // prime numbers is equal to 4
        // return 1.
        if (countOfPrimes == 4)
        {
            return 1;
        }
        return 0;
    }
 
    int val = dp[index][mask];
 
    // If the state has
    // already been computed
    if (val != -1)
    {
        return val;
    }
 
    val = 0;
 
    // If current position is 1, then any
    // digit from [1-9] can be placed.
    // If N = 1, 0 can be also placed.
    if (index == 1)
    {
        for(int digit = (N == 1 ? 0 : 1);
                digit <= 9; ++digit)
        {
             
            // If the digit is a prime number,
            // set the index of the digit to 1
            // in the bitmask.
            if (primeIndex.containsKey(digit))
            {
                int newMask = mask | (1 << primeIndex.get(digit));
                val += countOfNumbers(index + 1,
                                      newMask, N);
            }
 
            else
            {
                val += countOfNumbers(index + 1, mask, N);
            }
        }
    }
 
    // For remaining positions,
    // any digit from [0-9] can be placed
    else
    {
        for(int digit = 0; digit <= 9; ++digit)
        {
             
            // If the digit is a prime number,
            // set the index of the digit to 1
            // in the bitmask.
            if (primeIndex.containsKey(digit))
            {
                int newMask = mask | (1 << primeIndex.get(digit));
                val += countOfNumbers(index + 1, newMask, N);
            }
            else
            {
                val += countOfNumbers(index + 1, mask, N);
            }
        }
    }
 
    // Return the answer.
    return val;
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Initializing dp array with -1.
    for(int i = 0; i < 100; i++)
    {
        for(int j = 0; j < (1 << 4); j++)
        {
            dp[i][j] = -1;
        }
    }
 
    // Indexing prime numbers in
    // ascending order
    primeIndex.put(2, 0);
    primeIndex.put(3, 1);
    primeIndex.put(5, 2);
    primeIndex.put(7, 3);
 
    // Given Input
    int N = 4;
 
    // Function call
    System.out.println(countOfNumbers(1, 0, N));
}
}
 
// This code is contributed by maddler


Python3
# Python3 program for the above approach
 
# Stores the dp-states
dp = [[-1 for i in range(1<<4)] for j in range(100)]
 
# Stores the index of prime numbers
primeIndex = {}
 
def  countSetBits(n):
    count = 0
    while (n):
        count += n & 1
        n >>= 1
    return count
 
def countOfNumbers(index, mask, N):
    # If index = N+1
    if (index == N + 1):
 
        # Find count of distinct
        # prime numbers by counting
        # number of set bits.
        countOfPrimes = countSetBits(mask);
 
        # If count of distinct
        # prime numbers is equal to 4
        # return 1.
        if (countOfPrimes == 4):
            return 1
        return 0
 
    val = dp[index][mask]
 
    # If the state has
    # already been computed
    if (val != -1):
        return val
 
    val = 0
 
    # If current position is 1,
    # then any digit from [1-9] can be placed.
    # If N = 1, 0 can be also placed.
    if (index == 1):
        digit = 0 if N == 1 else 1
        while(digit <= 9):
            # If the digit is a prime number,
            # set the index of the
            # digit to 1 in the bitmask.
            if (digit in primeIndex):
                val += countOfNumbers(index + 1,mask | (1 << primeIndex[digit]), N)
 
            else:
                val += countOfNumbers(index + 1, mask, N)
 
            digit += 1
 
    # For remaining positions,
    # any digit from [0-9] can be placed
    else:
        for digit in range(10):
            # If the digit is a prime number,
            # set the index of the
            # digit to 1 in the bitmask.
            if (digit in primeIndex):
                val += countOfNumbers(index + 1,mask | (1 << primeIndex[digit]), N)
 
            else:
                val += countOfNumbers(index + 1, mask, N)
 
    # Return the answer.
    return val
 
# Driver Code
if __name__ == '__main__':
    # Initializing dp array with -1.
    # Indexing prime numbers in
    # ascending order
    primeIndex[2] = 0
    primeIndex[3] = 1
    primeIndex[5] = 2
    primeIndex[7] = 3
 
    # Given Input
    N = 4
 
    # Function call.
    print(countOfNumbers(1, 0, N))
     
    # This code is contributed by ipg2016107.


输出
24

时间复杂度: O(N *10 * 2 4 )
辅助空间: O(N * 2 4 )