Count number of ways to generate digit K at the end.
Last Updated :
18 Oct, 2023
Given an array arr[] containing N elements, each element is between 0 to 9. The task is to count the number of ways modulo 109 + 7 these operations can be performed so that at the end array with digit K left. Following operations are allowed on the array and any of the operations can be performed more than one time.
- Remove two leftmost elements x and y from the array and insert (x + y) % 10 at the left end of the array.
- Remove two leftmost elements x and y from the array and insert (x * y) % 10 at the left end of the array.
Examples:
Input: arr[] = {2, 7, 6}, K = 4
Output: 2
Explanation: Perform Operation 1 first and then Operation 2: The sequence becomes (2, 7, 6) ? (9, 6)? (4).
Perform Operation 2 first and then Operation 2 again: The sequence becomes (2, 7, 6) ? (4, 6)? (4).
Input: arr[] = {0 1 2 3 4}, K = 0
Output: 6
Naive approach: The problem can be solved by using the following idea:
Basic way to solve this problem is to generate all 2N combinations by recursive brute force.
Time Complexity: O(2N)
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. It can be observed that there are N * 10 states but the recursive function is called exponential times. That means that some states are called repeatedly. So the idea is to store the value of states.
Follow the steps below to solve the problem:
- Create a recursive function that takes three parameters i representing i’th index, j representing the leftmost array element after the operation, and K representing the digit whose count at the end has to find out.
- Check the base case if j is equal to K return 1 else return 0.
- Create a 2d array of dp[100001][10] with 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].
- Initialize a variable and to store the final result.
- Perform operation 1 by making recursive call ans+= call( i+ 1, (j + arr[i + 1])).
- Perform operation 2 by making recursive call ans+= call(i + 1, (j * arr[i + 1])).
- Return the answer.
Below is the implementation of the above approach.
C++
#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
int dp[100001][10];
int recur( int i, int j, int K, int arr[], int N)
{
if (i == N - 1) {
if (j == K)
return 1;
else
return 0;
}
if (dp[i][j] != -1)
return dp[i][j];
int ans = 0;
ans += recur(i + 1, (j + arr[i + 1]) % 10, K, arr, N)
% mod;
ans += recur(i + 1, (j * arr[i + 1]) % 10, K, arr, N)
% mod;
return dp[i][j] = ans;
}
void countWaysK( int arr[], int N, int K)
{
memset (dp, -1, sizeof (dp));
cout << recur(0, arr[0], K, arr, N) << endl;
}
int main()
{
int arr[] = { 2, 7, 6 };
int N = sizeof (arr) / sizeof (arr[0]);
int K = 4;
countWaysK(arr, N, K);
int arr1[] = { 0, 1, 2, 3, 4 };
int N1 = sizeof (arr1) / sizeof (arr[0]);
int K1 = 0;
countWaysK(arr1, N1, K1);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static final int mod = ( int )(1e9 + 7 );
static int [][] dp;
static int recur( int i, int j, int K, int [] arr, int N)
{
if (i == N - 1 ) {
if (j == K)
return 1 ;
else
return 0 ;
}
if (dp[i][j] != - 1 )
return dp[i][j];
int ans = 0 ;
ans += recur(i + 1 , (j + arr[i + 1 ]) % 10 , K, arr,
N)
% mod;
ans += recur(i + 1 , (j * arr[i + 1 ]) % 10 , K, arr,
N)
% mod;
return dp[i][j] = ans;
}
static void countWaysK( int [] arr, int N, int K)
{
dp = new int [ 100001 ][ 10 ];
for ( int [] row : dp) {
Arrays.fill(row, - 1 );
}
System.out.println(recur( 0 , arr[ 0 ], K, arr, N));
}
public static void main(String[] args)
{
int [] arr = { 2 , 7 , 6 };
int N = arr.length;
int K = 4 ;
countWaysK(arr, N, K);
int [] arr1 = { 0 , 1 , 2 , 3 , 4 };
int N1 = arr1.length;
int K1 = 0 ;
countWaysK(arr1, N1, K1);
}
}
|
Python3
mod = 1e9 + 7
dp = [[ - 1 for i in range ( 10 )] for j in range ( 100001 )]
def recur(i, j, K, arr, N):
if (i = = N - 1 ):
if (j = = K):
return 1
else :
return 0
if (dp[i][j]! = - 1 ):
return dp[i][j]
ans = 0
ans + = recur(i + 1 , (j + arr[i + 1 ]) % 10 , K, arr, N) % mod
ans + = recur(i + 1 , (j * arr[i + 1 ]) % 10 , K, arr, N) % mod
dp[i][j] = int (ans)
return dp[i][j]
def countWaysK(arr, N, K):
for i in range ( len (dp)):
for j in range ( len (dp[ 0 ])):
dp[i][j] = - 1
print (recur( 0 , arr[ 0 ], K, arr, N))
arr = [ 2 , 7 , 6 ]
N = len (arr)
K = 4
countWaysK(arr, N, K)
arr1 = [ 0 , 1 , 2 , 3 , 4 ]
N1 = len (arr1)
K1 = 0
countWaysK(arr1, N1, K1)
|
C#
using System;
using System.Linq;
public class GFG {
static readonly int mod = ( int )(1e9 + 7);
static int [][] dp;
static int recur( int i, int j, int K, int [] arr, int N)
{
if (i == N - 1)
{
if (j == K)
return 1;
else
return 0;
}
if (dp[i][j] != -1)
return dp[i][j];
int ans = 0;
ans += recur(i + 1, (j + arr[i + 1]) % 10, K, arr,
N)
% mod;
ans += recur(i + 1, (j * arr[i + 1]) % 10, K, arr,
N)
% mod;
return dp[i][j] = ans;
}
static void countWaysK( int [] arr, int N, int K)
{
dp = Enumerable.Range(0, 100001)
.Select(
x
=> Enumerable.Range(0, 10).ToArray())
.ToArray();
for ( int i = 0; i < dp.Length; i++) {
for ( int j = 0; j < dp[i].Length; j++) {
dp[i][j] = -1;
}
}
Console.WriteLine(recur(0, arr[0], K, arr, N));
}
static public void Main()
{
int [] arr = { 2, 7, 6 };
int N = arr.Length;
int K = 4;
countWaysK(arr, N, K);
int [] arr1 = { 0, 1, 2, 3, 4 };
int N1 = arr1.Length;
int K1 = 0;
countWaysK(arr1, N1, K1);
}
}
|
Javascript
let mod = 1e9 + 7;
let dp = new Array(100001);
for (let i = 0; i < 100001; i++){
dp[i] = new Array(10).fill(-1);
}
function recur(i, j, K, arr, N)
{
if (i == N - 1) {
if (j == K)
return 1;
else
return 0;
}
if (dp[i][j] != -1)
return dp[i][j];
let ans = 0;
ans += recur(i + 1, (j + arr[i + 1]) % 10, K, arr, N)
% mod;
ans += recur(i + 1, (j * arr[i + 1]) % 10, K, arr, N)
% mod;
return dp[i][j] = ans;
}
function countWaysK(arr, N, K)
{
console.log(recur(0, arr[0], K, arr, N))
}
let arr = [2, 7, 6 ];
let N = arr.length;
let K = 4;
countWaysK(arr, N, K);
let arr1 = [0, 1, 2, 3, 4];
let N1 = arr1.length;
let K1 = 0;
countWaysK(arr1, N1, K1);
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Efficient approach : Using DP Tabulation method ( Iterative approach )
The approach to solve this problem is same but DP tabulation(bottom-up) method is better then Dp + memoization(top-down) because memoization method needs extra stack space of recursion calls.
Implementation :
C++
#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
void countWaysK( int arr[], int N, int K)
{
int dp[N][10];
memset (dp, 0, sizeof (dp));
for ( int j = 0; j < 10; j++) {
if (j == arr[0]) {
dp[0][j] = 1;
}
}
for ( int i = 1; i < N; i++) {
for ( int j = 0; j < 10; j++) {
dp[i][(j + arr[i]) % 10]
= (dp[i][(j + arr[i]) % 10] + dp[i - 1][j])
% mod;
dp[i][(j * arr[i]) % 10]
= (dp[i][(j * arr[i]) % 10] + dp[i - 1][j])
% mod;
}
}
cout << dp[N - 1][K] << endl;
}
int main()
{
int arr[] = { 2, 7, 6 };
int N = sizeof (arr) / sizeof (arr[0]);
int K = 4;
countWaysK(arr, N, K);
int arr1[] = { 0, 1, 2, 3, 4 };
int N1 = sizeof (arr1) / sizeof (arr[0]);
int K1 = 0;
countWaysK(arr1, N1, K1);
return 0;
}
|
Java
import java.util.Arrays;
public class Main {
static final int mod = ( int ) 1e9 + 7 ;
public static void countWaysK( int [] arr, int N, int K) {
int [][] dp = new int [N][ 10 ];
for ( int [] row : dp) {
Arrays.fill(row, 0 );
}
for ( int j = 0 ; j < 10 ; j++) {
if (j == arr[ 0 ]) {
dp[ 0 ][j] = 1 ;
}
}
for ( int i = 1 ; i < N; i++) {
for ( int j = 0 ; j < 10 ; j++) {
dp[i][(j + arr[i]) % 10 ] = (dp[i][(j + arr[i]) % 10 ] + dp[i - 1 ][j]) % mod;
dp[i][(j * arr[i]) % 10 ] = (dp[i][(j * arr[i]) % 10 ] + dp[i - 1 ][j]) % mod;
}
}
System.out.println(dp[N - 1 ][K]);
}
public static void main(String[] args) {
int [] arr = { 2 , 7 , 6 };
int N = arr.length;
int K = 4 ;
countWaysK(arr, N, K);
int [] arr1 = { 0 , 1 , 2 , 3 , 4 };
int N1 = arr1.length;
int K1 = 0 ;
countWaysK(arr1, N1, K1);
}
}
|
Python3
mod = 10 * * 9 + 7
def countWaysK(arr, N, K):
dp = [[ 0 ] * 10 for _ in range (N)]
for j in range ( 10 ):
if j = = arr[ 0 ]:
dp[ 0 ][j] = 1
for i in range ( 1 , N):
for j in range ( 10 ):
dp[i][(j + arr[i]) % 10 ] = (dp[i][(j + arr[i]) % 10 ] + dp[i - 1 ][j]) % mod
dp[i][(j * arr[i]) % 10 ] = (dp[i][(j * arr[i]) % 10 ] + dp[i - 1 ][j]) % mod
print (dp[N - 1 ][K])
arr = [ 2 , 7 , 6 ]
N = len (arr)
K = 4
countWaysK(arr, N, K)
arr1 = [ 0 , 1 , 2 , 3 , 4 ]
N1 = len (arr1)
K1 = 0
countWaysK(arr1, N1, K1)
|
C#
using System;
namespace CodeTranslationAssistant
{
class Program
{
const int mod = 1000000007;
static void CountWaysK( int [] arr, int N, int K)
{
int [,] dp = new int [N, 10];
for ( int i = 0; i < N; i++)
{
for ( int j = 0; j < 10; j++)
{
dp[i, j] = 0;
}
}
for ( int j = 0; j < 10; j++)
{
if (j == arr[0])
{
dp[0, j] = 1;
}
}
for ( int i = 1; i < N; i++)
{
for ( int j = 0; j < 10; j++)
{
dp[i, (j + arr[i]) % 10] =
(dp[i, (j + arr[i]) % 10] + dp[i - 1, j]) % mod;
dp[i, (j * arr[i]) % 10] =
(dp[i, (j * arr[i]) % 10] + dp[i - 1, j]) % mod;
}
}
Console.WriteLine(dp[N - 1, K]);
}
static void Main( string [] args)
{
int [] arr = { 2, 7, 6 };
int N = arr.Length;
int K = 4;
CountWaysK(arr, N, K);
int [] arr1 = { 0, 1, 2, 3, 4 };
int N1 = arr1.Length;
int K1 = 0;
CountWaysK(arr1, N1, K1);
}
}
}
|
Javascript
const mod = 10**9 + 7;
function countWaysK(arr, N, K) {
const dp = new Array(N);
for (let i = 0; i < N; i++) {
dp[i] = new Array(10).fill(0);
}
for (let j = 0; j < 10; j++) {
if (j === arr[0]) {
dp[0][j] = 1;
}
}
for (let i = 1; i < N; i++) {
for (let j = 0; j < 10; j++) {
dp[i][(j + arr[i]) % 10] = (dp[i][(j + arr[i]) % 10] + dp[i - 1][j]) % mod;
dp[i][(j * arr[i]) % 10] = (dp[i][(j * arr[i]) % 10] + dp[i - 1][j]) % mod;
}
}
console.log(dp[N - 1][K]);
}
const arr = [2, 7, 6];
const N = arr.length;
const K = 4;
countWaysK(arr, N, K);
const arr1 = [0, 1, 2, 3, 4];
const N1 = arr1.length;
const K1 = 0;
countWaysK(arr1, N1, K1);
|
Time Complexity: O(N*10)
Auxiliary Space: O(N*10)
Related Articles:
Share your thoughts in the comments
Please Login to comment...