给定一个正整数N ,任务是计算N位数字的数量,使得数字中不同的奇数和不同的偶数位数相同。
例子:
Input: N = 2
Output : 45
Explanation:
For a 2-digit number, in order to satisfy the condition, the first digit can be even and second digit odd, or the second digit can be odd and first digit even. For the first case there are (4 X 5) = 20 possibilities and for the second case there are (5 X 5) = 25 possibilities. Hence the answer is 45.
Input: N = 3
Output: 135
朴素方法:解决给定问题的最简单方法是生成所有可能的N位数字,并计算那些不同奇数和偶数位数相同的数字。检查所有数字后,打印计数值作为结果的总数字计数。
时间复杂度: O(N *10 N )
辅助空间: O(1)
高效方法:上述方法也可以使用动态规划进行优化,因为上述问题具有重叠子问题和最优子结构。子问题可以存储在dp[][][] 表记忆中,其中dp[index][evenMask][oddMask]存储从第i个索引位置到最后的答案,其中evenMask用于确定不同偶数的数量数字中的位数,而oddMask用于使用位掩码确定数字中不同奇数位数的数量。请按照以下步骤解决问题:
- 初始化一个全局多维数组dp[100][1<<5][1<<5],其中所有值都为 -1,用于存储每个递归调用的结果。
- 通过执行以下步骤定义一个递归函数,比如countOfNumbers(index, evenMask,oddMask, N)
- 如果索引的值等于(N + 1),
- 计算evenMask和oddMask中设置位的计数。
- 如果它们的计数相同,则不同的偶数和奇数位数相同,因此返回1作为有效的 N 位数。
- 否则返回0 。
- 如果已经计算了状态dp[index][evenMask][oddMask] 的结果,则返回此值dp[index][evenMask][oddMask] 。
- 如果当前索引为1 ,则可以放置[1-9] 中的任何数字,如果N = 1 ,则也可以放置0 。
- 对于所有其他索引,可以放置[0-9] 中的任何数字。
- 对于任何放置的数字,根据数字的奇偶校验,将evenMask或oddMask 的第(digit / 2)位设置为1 。它表示数字中存在特定数字。由于我们将数字除以2 ,大小为(1 << 5) 的位掩码对于每个oddMask和evenMask就足够了。
- 进行有效放置后,递归调用(index + 1)的countOfNumbers函数。
- 返回所有可能的有效数字位置的总和作为答案。
- 如果索引的值等于(N + 1),
- 完成上述步骤后,打印函数countOfNumbers(1, 0, 0, N ) 返回的值作为结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Stores the dp-states
int dp[100][1 << 5][1 << 5];
// Recursive Function to find number
// of N-digit numbers which has equal
// count of distinct odd & even digits
int countOfNumbers(int index, int evenMask,
int oddMask, int N)
{
// If index is N + 1
if (index == N + 1) {
// Find the count of set bits
// in the evenMask
int countOfEvenDigits
= __builtin_popcount(evenMask);
// Find the count of set bits
// in the oddMask
int countOfOddDigits
= __builtin_popcount(oddMask);
// If the count of set bits in both
// masks are equal then return 1
// as they have equal number of
// distinct odd and even digits
if (countOfOddDigits
== countOfEvenDigits) {
return 1;
}
return 0;
}
int& val = dp[index][evenMask][oddMask];
// 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 digit is odd
if (digit & 1) {
// Set the (digit/2)th bit
// of the oddMask
val += countOfNumbers(
index + 1, evenMask,
oddMask | (1 << (digit / 2)), N);
}
// Set the (digit/2)th bit
// of the number evenMask
else {
val += countOfNumbers(
index + 1,
evenMask | (1 << (digit / 2)),
oddMask, N);
}
}
}
// For remaining positions, any
// digit from [0-9] can be placed
else {
for (int digit = 0;
digit <= 9; ++digit) {
// If digit is odd
if (digit & 1) {
// Set the (digit/2)th
// bit of oddMask
val += countOfNumbers(
index + 1, evenMask,
oddMask | (1 << (digit / 2)), N);
}
else {
// Set the (digit/2)th
// bit of evenMask
val += countOfNumbers(
index + 1,
evenMask | (1 << (digit / 2)),
oddMask, N);
}
}
}
// Return the answer
return val;
}
// Function to find number of N-digit
// numbers which has equal count of
// distinct odd and even digits
void countNDigitNumber(int N)
{
// Initialize dp array with -1
memset(dp, -1, sizeof dp);
// Function Call
cout << countOfNumbers(1, 0, 0, N);
}
// Driver Code
int main()
{
int N = 3;
countNDigitNumber(N);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
import java.util.*;
class GFG{
// Stores the dp-states
static int[][][] dp = new int[100][1 << 5][1 << 5];
// Returns number of set bits in a number
static int __builtin_popcount(int n)
{
int d, t = 0;
while(n > 0)
{
d = n % 2;
n = n / 2;
if (d == 1)
t++;
}
return t;
}
// Recursive Function to find number
// of N-digit numbers which has equal
// count of distinct odd & even digits
static int countOfNumbers(int index, int evenMask,
int oddMask, int N)
{
// If index is N + 1
if (index == N + 1)
{
// Find the count of set bits
// in the evenMask
int countOfEvenDigits = __builtin_popcount(evenMask);
// Find the count of set bits
// in the oddMask
int countOfOddDigits = __builtin_popcount(oddMask);
// If the count of set bits in both
// masks are equal then return 1
// as they have equal number of
// distinct odd and even digits
if (countOfOddDigits == countOfEvenDigits)
{
return 1;
}
return 0;
}
int val = dp[index][evenMask][oddMask];
// 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 digit is odd
if ((digit & 1) != 0)
{
// Set the (digit/2)th bit
// of the oddMask
val += countOfNumbers(
index + 1, evenMask,
oddMask | (1 << (digit / 2)), N);
}
// Set the (digit/2)th bit
// of the number evenMask
else
{
val += countOfNumbers(
index + 1,
evenMask | (1 << (digit / 2)),
oddMask, N);
}
}
}
// For remaining positions, any
// digit from [0-9] can be placed
else
{
for(int digit = 0; digit <= 9; ++digit)
{
// If digit is odd
if ((digit & 1) != 0)
{
// Set the (digit/2)th
// bit of oddMask
val += countOfNumbers(
index + 1, evenMask,
oddMask | (1 << (digit / 2)), N);
}
else
{
// Set the (digit/2)th
// bit of evenMask
val += countOfNumbers(
index + 1,
evenMask | (1 << (digit / 2)),
oddMask, N);
}
}
}
// Return the answer
return val;
}
// Function to find number of N-digit
// numbers which has equal count of
// distinct odd and even digits
static void countNDigitNumber(int N)
{
// Initialize dp array with -1
for(int i = 0; i < 100; i++)
{
for(int j = 0; j < (1 << 5); j++)
{
for(int k = 0; k < (1 << 5); k++)
{
dp[i][j][k] = -1;
}
}
}
// Function Call
System.out.println(countOfNumbers(1, 0, 0, N));
}
// Driver code
public static void main(String[] args)
{
int N = 3;
countNDigitNumber(N);
}
}
// This code is contributed by sanjoy_62
C#
// C# program for the above approach
using System;
class GFG{
// Stores the dp-states
static int[,,] dp = new int[100, 1 << 5, 1 << 5];
// Returns number of set bits in a number
static int __builtin_popcount(int n)
{
int d, t = 0;
while(n > 0)
{
d = n % 2;
n = n / 2;
if (d == 1)
t++;
}
return t;
}
// Recursive Function to find number
// of N-digit numbers which has equal
// count of distinct odd & even digits
static int countOfNumbers(int index, int evenMask,
int oddMask, int N)
{
// If index is N + 1
if (index == N + 1)
{
// Find the count of set bits
// in the evenMask
int countOfEvenDigits = __builtin_popcount(evenMask);
// Find the count of set bits
// in the oddMask
int countOfOddDigits = __builtin_popcount(oddMask);
// If the count of set bits in both
// masks are equal then return 1
// as they have equal number of
// distinct odd and even digits
if (countOfOddDigits == countOfEvenDigits)
{
return 1;
}
return 0;
}
int val = dp[index, evenMask, oddMask];
// 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 digit is odd
if ((digit & 1) != 0)
{
// Set the (digit/2)th bit
// of the oddMask
val += countOfNumbers(
index + 1, evenMask,
oddMask | (1 << (digit / 2)), N);
}
// Set the (digit/2)th bit
// of the number evenMask
else
{
val += countOfNumbers(
index + 1,
evenMask | (1 << (digit / 2)),
oddMask, N);
}
}
}
// For remaining positions, any
// digit from [0-9] can be placed
else
{
for(int digit = 0; digit <= 9; ++digit)
{
// If digit is odd
if ((digit & 1) != 0)
{
// Set the (digit/2)th
// bit of oddMask
val += countOfNumbers(
index + 1, evenMask,
oddMask | (1 << (digit / 2)), N);
}
else
{
// Set the (digit/2)th
// bit of evenMask
val += countOfNumbers(
index + 1,
evenMask | (1 << (digit / 2)),
oddMask, N);
}
}
}
// Return the answer
return val;
}
// Function to find number of N-digit
// numbers which has equal count of
// distinct odd and even digits
static void countNDigitNumber(int N)
{
// Initialize dp array with -1
for(int i = 0; i < 100; i++)
{
for(int j = 0; j < (1 << 5); j++)
{
for(int k = 0; k < (1 << 5); k++)
{
dp[i, j, k] = -1;
}
}
}
// Function Call
Console.Write(countOfNumbers(1, 0, 0, N));
}
// Driver Code
public static void Main()
{
int N = 3;
countNDigitNumber(N);
}
}
// This code is contributed by target_2.
135
时间复杂度: O(N *10 * 2 5 * 2 5 )
辅助空间: O(N * 2 5 * 2 5 )