给定一个正整数N ,任务是计算包含所有个位数素数的N位数字的数量。
例子:
Input: N = 4
Output: 24
Explanation: The number of single digit primes is 4 i.e.{2, 3, 5, 7}. Hence number of ways to arrange 4 numbers in 4 places is 4! = 24.
Input: N = 5
Output: 936
朴素方法:解决给定问题的最简单方法是生成所有可能的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函数。
- 返回所有可能的有效数字位置的总和作为答案。
- 如果索引的值等于(N + 1),
- 打印函数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 )