Number of integers of size N having even sum of digits
Last Updated :
30 Jan, 2023
Given the number N, the task is to count a number of ways to create a number with digit size N with the sum of digits even. print the answer modulo 109 + 7. (1 <= N <= 105)
Examples:
Input: N = 1
Output: 4
Explanation: 2, 4, 6 and 8 are the numbers.
Input: N = 2
Output: 45
Explanation: 11, 13, 15, 17, 19, 20, 22, 24, 26, 28, 31, 33, 35, 37, 39, 40, 42, 44, 46, 48, 51, 53, 55, 57, 59, 60, 62, 64, 66, 68, 71, 73, 75, 77, 79, 80, 82, 84, 86, 88, 91, 93, 95, 97, and 99 are the possible numbers.
Naive approach: The basic way to solve the problem is as follows:
The basic way to solve this problem is to generate all possible combinations by using a recursive approach.
Time Complexity: O(10N)
Auxiliary Space: O(1)
Efficient Approach: The above approach can be optimized based on the following idea:
Dynamic programming can be used to solve this problem. For solving this problem its very simple to make finite automata machine for states with following transitions:
- dp[i][j] represents number of ways of creating numbers with i digits and j represents current state of state machine.
- It can be observed that the recursive function is called exponential times. That means that some states are called repeatedly.
- So the idea is to store the value of each state. This can be done by using the stored value of a state and whenever the function is called, return the stored value without computing again.
Follow the steps below to solve the problem:
- Create a recursive function that takes two parameters representing i’th position to be filled with digit and j representing the current state of Finite State Machine.
- Call the recursive function for choosing all digits from 0 to 9.
- Base case if digit of size N formed return 1 if the current state even else returns 0.
- Create a 2d array of dp[N][3] initially filled with -1.
- If the answer for a particular state is computed then save it in dp[i][j].
- If the answer for a particular state is already computed then just return dp[i][j].
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
const int MOD = 1e9 + 7;
int dp[1000001][3];
int recur( int i, int j)
{
if (i == 0) {
if (j == 2)
return 1;
else
return 0;
}
if (dp[i][j] != -1)
return dp[i][j];
int ans = 0;
if (j == 0) {
for ( int k = 1; k <= 9; k += 2) {
ans += recur(i - 1, 1);
ans %= MOD;
}
for ( int k = 2; k <= 8; k += 2) {
ans += recur(i - 1, 2);
ans %= MOD;
}
}
else if (j == 1) {
for ( int k = 1; k <= 9; k += 2) {
ans += recur(i - 1, 2);
ans %= MOD;
}
for ( int k = 2; k <= 8; k += 2) {
ans += recur(i - 1, 1);
ans %= MOD;
}
}
else {
for ( int k = 1; k <= 9; k += 2) {
ans += recur(i - 1, 1);
ans %= MOD;
}
for ( int k = 0; k <= 8; k += 2) {
ans += recur(i - 1, 2);
ans %= MOD;
}
}
return dp[i][j] = ans;
}
int countWaysTo( int N)
{
memset (dp, -1, sizeof (dp));
return recur(N, 0);
}
int main()
{
int N = 1;
cout << countWaysTo(N) << endl;
int N1 = 2;
cout << countWaysTo(N1) << endl;
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static int MOD = 1000000000 + 7 ;
static int dp[][] = new int [ 1000001 ][ 3 ];
static int recur( int i, int j)
{
if (i == 0 ) {
if (j == 2 )
return 1 ;
else
return 0 ;
}
if (dp[i][j] != - 1 )
return dp[i][j];
int ans = 0 ;
if (j == 0 ) {
for ( int k = 1 ; k <= 9 ; k += 2 ) {
ans += recur(i - 1 , 1 );
ans %= MOD;
}
for ( int k = 2 ; k <= 8 ; k += 2 ) {
ans += recur(i - 1 , 2 );
ans %= MOD;
}
}
else if (j == 1 ) {
for ( int k = 1 ; k <= 9 ; k += 2 ) {
ans += recur(i - 1 , 2 );
ans %= MOD;
}
for ( int k = 2 ; k <= 8 ; k += 2 ) {
ans += recur(i - 1 , 1 );
ans %= MOD;
}
}
else {
for ( int k = 1 ; k <= 9 ; k += 2 ) {
ans += recur(i - 1 , 1 );
ans %= MOD;
}
for ( int k = 0 ; k <= 8 ; k += 2 ) {
ans += recur(i - 1 , 2 );
ans %= MOD;
}
}
return dp[i][j] = ans;
}
static int countWaysTo( int N)
{
for ( int i= 0 ;i< 1000001 ;i++)
{
for ( int j= 0 ;j< 3 ;j++)
{
dp[i][j]=- 1 ;
}
}
return recur(N, 0 );
}
public static void main(String[] args)
{
int N = 1 ;
System.out.println(countWaysTo(N));
int N1 = 2 ;
System.out.println(countWaysTo(N1));
}
}
|
Python3
MOD = int ( 1e9 + 7 )
dp = [[ - 1 for _ in range ( 3 )] for _ in range ( 1000001 )]
def recur(i: int , j: int ) - > int :
if i = = 0 :
if j = = 2 :
return 1
else :
return 0
if dp[i][j] ! = - 1 :
return dp[i][j]
ans = 0
if j = = 0 :
for k in range ( 1 , 10 , 2 ):
ans + = recur(i - 1 , 1 )
ans % = MOD
for k in range ( 2 , 9 , 2 ):
ans + = recur(i - 1 , 2 )
ans % = MOD
elif j = = 1 :
for k in range ( 1 , 10 , 2 ):
ans + = recur(i - 1 , 2 )
ans % = MOD
for k in range ( 2 , 9 , 2 ):
ans + = recur(i - 1 , 1 )
ans % = MOD
else :
for k in range ( 1 , 10 , 2 ):
ans + = recur(i - 1 , 1 )
ans % = MOD
for k in range ( 0 , 9 , 2 ):
ans + = recur(i - 1 , 2 )
ans % = MOD
dp[i][j] = ans
return ans
def countWaysTo(N: int ) - > int :
return recur(N, 0 )
if __name__ = = "__main__" :
N = 1
print (countWaysTo(N))
N1 = 2
print (countWaysTo(N1))
|
C#
using System;
using System.Collections.Generic;
class GFG {
static int MOD = 1000000007;
static int [,] dp= new int [1000001,3];
static int recur( int i, int j)
{
if (i == 0) {
if (j == 2)
return 1;
else
return 0;
}
if (dp[i,j] != -1)
return dp[i,j];
int ans = 0;
if (j == 0) {
for ( int k = 1; k <= 9; k += 2) {
ans += recur(i - 1, 1);
ans %= MOD;
}
for ( int k = 2; k <= 8; k += 2) {
ans += recur(i - 1, 2);
ans %= MOD;
}
}
else if (j == 1) {
for ( int k = 1; k <= 9; k += 2) {
ans += recur(i - 1, 2);
ans %= MOD;
}
for ( int k = 2; k <= 8; k += 2) {
ans += recur(i - 1, 1);
ans %= MOD;
}
}
else {
for ( int k = 1; k <= 9; k += 2) {
ans += recur(i - 1, 1);
ans %= MOD;
}
for ( int k = 0; k <= 8; k += 2) {
ans += recur(i - 1, 2);
ans %= MOD;
}
}
return dp[i,j] = ans;
}
static int countWaysTo( int N)
{
for ( int i=0; i<1000001; i++)
{
for ( int j=0;j<3; j++)
dp[i,j]=-1;
}
return recur(N, 0);
}
public static void Main()
{
int N = 1;
Console.Write(countWaysTo(N)+ "\n" );
int N1 = 2;
Console.Write(countWaysTo(N1)+ "\n" );
}
}
|
Javascript
const MOD = 1e9 + 7;
let dp= new Array(1000001)
for (let i=0; i<1000001; i++)
dp[i]= new Array(3).fill(-1);
function recur( i, j)
{
if (i == 0) {
if (j == 2)
return 1;
else
return 0;
}
if (dp[i][j] != -1)
return dp[i][j];
let ans = 0;
if (j == 0) {
for (let k = 1; k <= 9; k += 2) {
ans += recur(i - 1, 1);
ans %= MOD;
}
for (let k = 2; k <= 8; k += 2) {
ans += recur(i - 1, 2);
ans %= MOD;
}
}
else if (j == 1) {
for (let k = 1; k <= 9; k += 2) {
ans += recur(i - 1, 2);
ans %= MOD;
}
for (let k = 2; k <= 8; k += 2) {
ans += recur(i - 1, 1);
ans %= MOD;
}
}
else {
for (let k = 1; k <= 9; k += 2) {
ans += recur(i - 1, 1);
ans %= MOD;
}
for (let k = 0; k <= 8; k += 2) {
ans += recur(i - 1, 2);
ans %= MOD;
}
}
return dp[i][j] = ans;
}
function countWaysTo( N)
{
return recur(N, 0);
}
let N = 1;
console.log(countWaysTo(N));
let N1 = 2;
console.log(countWaysTo(N1));
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Related Articles:
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...