包含所有个位数素数的N位数的计数

156 阅读4分钟

包含所有个位数素数的N位数的计数

  • 最后更新 : 2021年8月6日

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

举例说明。

输入。 N = 4
输出。 24
解释。 个位数素数的数量是4,即{2, 3, 5, 7}。因此,在4个地方排列4个数字的方法是4!=24。

输入。 N = 5
输出。 936

建议。请先在_{IDE}_上尝试你的方法,然后再继续求解。

天真的方法。 解决给定问题的最简单方法是生成所有可能的N位数,并计算那些包含所有个位数素数的数字。在对所有的数字进行检查后,将计数的值打印出来,作为结果的数字总计数。
时间复杂度。 O(N *10N)
**辅助空间。**O(1)

高效的方法。上 述方法也可以用动态编程来优化,因为它有重叠的子问题和最佳的子结构。子问题可以使用记忆法存储在dp[][]表中,其中dp[index][mask]存储从第1个 索引位置到最后的答案,其中mask用于存储到现在为止所包含的独立素数的数量。按照下面的步骤来解决这个问题。

  • 初始化一个全局多维数组 **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
    • 在进行有效放置后,递归 调用countOfNumbers函数**(index + 1)**。
    • 返回所有可能的有效位数的总和作为答案。
  • 打印函数**countOfNumbers(1, 0, N)**返回的值作为结果。

下面是上述方法的实现。

C++

// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
// Stores the dp-states
int dp[100][1 << 4];
// Stores the index of prime numbers
map<int,int> 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;
}

Python3

# Python 3 program for the above approach
# Stores the dp-states
dp= [[-1 for iin range(1<<4)]for jin 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 (digitin 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 digitin range(10):
# If the digit is a prime number,
# set the index of the
# digit to 1 in the bitmask.
if (digitin 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 *24)
辅助空间。O (N *24)

读者请注意!现在不要停止学习。掌握竞争性编程的所有重要数学概念。 CP课程的基本数学以适合学生的价格获得所有重要的数学概念。要完成从学习语言到DS Algo和更多的准备工作,请参考 完整的面试准备课程.

我的个人笔记 arrow_drop_up

保存