Given an N * N matrix arr[][] consisting of non-negative integers, the task is to find the number of ways to reach arr[N β 1][N β 1] with a non-zero AND value starting from the arr[0][0] by going down or right in every move. Whenever a cell arr[i][j] is reached, βANDβ value is updated as currentVal & arr[i][j].
Examples:Β
Input: arr[][] = {Β
{1, 1, 1},Β
{1, 1, 1},Β
{1, 1, 1}}
Output: 6Β
All the paths will give non-zero and value.Β
Thus, number of ways equals 6.
Input: arr[][] = {Β
{1, 1, 2},Β
{1, 2, 1},Β
{2, 1, 1}}Β
Output: 0Β Β
Approach: This problem can be solved using dynamic programming. First, we need to decide the states of the DP. For every cell arr[i][j] and a number X, we will store the number of ways to reach the arr[N β 1][N β 1] from arr[i][j] with non-zero AND where X is the AND value of path till now. Thus, our solution will use 3-dimensional dynamic programming, two for the coordinates of the cells and one for X.
The required recurrence relation is:Β
dp[i][j][X] = dp[i][j + 1][X & arr[i][j]] + dp[i + 1][j][X & arr[i][j]]Β Β
Below is the implementation of the above approach:Β Β
C++
// C++ implementation of the approach #include <bits/stdc++.h> #define n 3 #define maxV 20 using namespace std; Β
// 3d array to store // states of dp int dp[n][n][maxV]; Β
// Array to determine whether // a state has been solved before int v[n][n][maxV]; Β
// Function to return the count of required paths int countWays( int i, int j, int x, int arr[][n]) { Β
Β Β Β Β // Base cases Β Β Β Β if (i == n || j == n) Β Β Β Β Β Β Β Β return 0; Β
Β Β Β Β x = (x & arr[i][j]); Β Β Β Β if (x == 0) Β Β Β Β Β Β Β Β return 0; Β
Β Β Β Β if (i == n - 1 && j == n - 1) Β Β Β Β Β Β Β Β return 1; Β
Β Β Β Β // If a state has been solved before Β Β Β Β // it won't be evaluated again Β Β Β Β if (v[i][j][x]) Β Β Β Β Β Β Β Β return dp[i][j][x]; Β
Β Β Β Β v[i][j][x] = 1; Β
Β Β Β Β // Recurrence relation Β Β Β Β dp[i][j][x] = countWays(i + 1, j, x, arr) Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β + countWays(i, j + 1, x, arr); Β
Β Β Β Β return dp[i][j][x]; } Β
// Driver code int main() { Β Β Β Β int arr[n][n] = { { 1, 2, 1 }, Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β { 1, 1, 0 }, Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β { 2, 1, 1 } }; Β
Β Β Β Β cout << countWays(0, 0, arr[0][0], arr); Β
Β Β Β Β return 0; } |
Java
// Java implementation of the approach class GFG { Β
Β Β Β Β static int n = 3 ; Β Β Β Β static int maxV = 20 ; Β
Β Β Β Β // 3d array to store Β Β Β Β // states of dp Β Β Β Β static int [][][] dp = new int [n][n][maxV]; Β
Β Β Β Β // Array to determine whether Β Β Β Β // a state has been solved before Β Β Β Β static int [][][] v = new int [n][n][maxV]; Β
Β Β Β Β // Function to return the count of required paths Β Β Β Β static int countWays( int i, int j, Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β int x, int arr[][]) Β Β Β Β { Β
Β Β Β Β Β Β Β Β // Base cases Β Β Β Β Β Β Β Β if (i == n || j == n) { Β Β Β Β Β Β Β Β Β Β Β Β return 0 ; Β Β Β Β Β Β Β Β } Β
Β Β Β Β Β Β Β Β x = (x & arr[i][j]); Β Β Β Β Β Β Β Β if (x == 0 ) { Β Β Β Β Β Β Β Β Β Β Β Β return 0 ; Β Β Β Β Β Β Β Β } Β
Β Β Β Β Β Β Β Β if (i == n - 1 && j == n - 1 ) { Β Β Β Β Β Β Β Β Β Β Β Β return 1 ; Β Β Β Β Β Β Β Β } Β
Β Β Β Β Β Β Β Β // If a state has been solved before Β Β Β Β Β Β Β Β // it won't be evaluated again Β Β Β Β Β Β Β Β if (v[i][j][x] == 1 ) { Β Β Β Β Β Β Β Β Β Β Β Β return dp[i][j][x]; Β Β Β Β Β Β Β Β } Β
Β Β Β Β Β Β Β Β v[i][j][x] = 1 ; Β
Β Β Β Β Β Β Β Β // Recurrence relation Β Β Β Β Β Β Β Β dp[i][j][x] = countWays(i + 1 , j, x, arr) Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β + countWays(i, j + 1 , x, arr); Β
Β Β Β Β Β Β Β Β return dp[i][j][x]; Β Β Β Β } Β
Β Β Β Β // Driver code Β Β Β Β public static void main(String[] args) Β Β Β Β { Β Β Β Β Β Β Β Β int arr[][] = { { 1 , 2 , 1 }, Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β { 1 , 1 , 0 }, Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β { 2 , 1 , 1 } }; Β
Β Β Β Β Β Β Β Β System.out.println(countWays( 0 , 0 , arr[ 0 ][ 0 ], arr)); Β Β Β Β } } Β
// This code contributed by Rajput-Ji |
Python3
# Python3 implementation of the approach n = 3 maxV = 20 Β
# 3d array to store states of dp dp = [[[ 0 for i in range (maxV)] Β Β Β Β Β Β Β Β Β Β for i in range (n)] Β Β Β Β Β Β Β Β Β Β for i in range (n)] Β
# Array to determine whether # a state has been solved before v = [[[ 0 for i in range (maxV)] Β Β Β Β Β Β Β Β Β for i in range (n)] Β Β Β Β Β Β Β Β Β for i in range (n)] Β
# Function to return # the count of required paths def countWays(i, j, x, arr): Β
Β Β Β Β # Base cases Β Β Β Β if (i = = n or j = = n): Β Β Β Β Β Β Β Β return 0 Β
Β Β Β Β x = (x & arr[i][j]) Β Β Β Β if (x = = 0 ): Β Β Β Β Β Β Β Β return 0 Β
Β Β Β Β if (i = = n - 1 and j = = n - 1 ): Β Β Β Β Β Β Β Β return 1 Β
Β Β Β Β # If a state has been solved before Β Β Β Β # it won't be evaluated again Β Β Β Β if (v[i][j][x]): Β Β Β Β Β Β Β Β return dp[i][j][x] Β
Β Β Β Β v[i][j][x] = 1 Β
Β Β Β Β # Recurrence relation Β Β Β Β dp[i][j][x] = countWays(i + 1 , j, x, arr) + \ Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β countWays(i, j + 1 , x, arr); Β
Β Β Β Β return dp[i][j][x] Β
# Driver code arr = [[ 1 , 2 , 1 ], Β Β Β Β Β Β Β [ 1 , 1 , 0 ], Β Β Β Β Β Β Β [ 2 , 1 , 1 ]] Β
print (countWays( 0 , 0 , arr[ 0 ][ 0 ], arr)) Β
# This code is contributed by Mohit Kumar |
C#
// C# implementation of the approach using System; Β
class GFG { Β
Β Β Β Β static int n = 3; Β Β Β Β static int maxV = 20; Β
Β Β Β Β // 3d array to store Β Β Β Β // states of dp Β Β Β Β static int [,,] dp = new int [n, n, maxV]; Β
Β Β Β Β // Array to determine whether Β Β Β Β // a state has been solved before Β Β Β Β static int [,,] v = new int [n, n, maxV]; Β
Β Β Β Β // Function to return the count of required paths Β Β Β Β static int countWays( int i, int j, Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β int x, int [,]arr) Β Β Β Β { Β
Β Β Β Β Β Β Β Β // Base cases Β Β Β Β Β Β Β Β if (i == n || j == n) Β Β Β Β Β Β Β Β { Β Β Β Β Β Β Β Β Β Β Β Β return 0; Β Β Β Β Β Β Β Β } Β
Β Β Β Β Β Β Β Β x = (x & arr[i, j]); Β Β Β Β Β Β Β Β if (x == 0) Β Β Β Β Β Β Β Β { Β Β Β Β Β Β Β Β Β Β Β Β return 0; Β Β Β Β Β Β Β Β } Β
Β Β Β Β Β Β Β Β if (i == n - 1 && j == n - 1) Β Β Β Β Β Β Β Β { Β Β Β Β Β Β Β Β Β Β Β Β return 1; Β Β Β Β Β Β Β Β } Β
Β Β Β Β Β Β Β Β // If a state has been solved before Β Β Β Β Β Β Β Β // it won't be evaluated again Β Β Β Β Β Β Β Β if (v[i, j, x] == 1) Β Β Β Β Β Β Β Β { Β Β Β Β Β Β Β Β Β Β Β Β return dp[i, j, x]; Β Β Β Β Β Β Β Β } Β
Β Β Β Β Β Β Β Β v[i, j, x] = 1; Β
Β Β Β Β Β Β Β Β // Recurrence relation Β Β Β Β Β Β Β Β dp[i, j, x] = countWays(i + 1, j, x, arr) Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β + countWays(i, j + 1, x, arr); Β
Β Β Β Β Β Β Β Β return dp[i, j, x]; Β Β Β Β } Β
Β Β Β Β // Driver code Β Β Β Β public static void Main() Β Β Β Β { Β Β Β Β Β Β Β Β int [,]arr = { { 1, 2, 1 }, Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β { 1, 1, 0 }, Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β { 2, 1, 1 } }; Β
Β Β Β Β Console.WriteLine(countWays(0, 0, arr[0,0], arr)); Β Β Β Β } } Β
// This code is contributed by AnkitRai01 |
Javascript
<script> Β
// Javascript implementation of the approach var n = 3; var maxV = 20; Β
// 3d array to store // states of dp var dp = new Array(n); Β
for ( var i = 0; i<n; i++) { Β Β Β Β dp[i] = new Array(n); Β Β Β Β for ( var j =0; j<n;j++) Β Β Β Β { Β Β Β Β Β Β Β Β dp[i][j] = new Array(maxV); Β Β Β Β } } Β
var v = new Array(n); Β
// Array to determine whether // a state has been solved before for ( var i = 0; i<n; i++) { Β Β Β Β v[i] = new Array(n); Β Β Β Β for ( var j =0; j<n;j++) Β Β Β Β { Β Β Β Β Β Β Β Β v[i][j] = new Array(maxV); Β Β Β Β } } Β
// Function to return the count of required paths function countWays(i, j, x, arr) { Β
Β Β Β Β // Base cases Β Β Β Β if (i == n || j == n) Β Β Β Β Β Β Β Β return 0; Β
Β Β Β Β x = (x & arr[i][j]); Β Β Β Β if (x == 0) Β Β Β Β Β Β Β Β return 0; Β
Β Β Β Β if (i == n - 1 && j == n - 1) Β Β Β Β Β Β Β Β return 1; Β
Β Β Β Β // If a state has been solved before Β Β Β Β // it won't be evaluated again Β Β Β Β if (v[i][j][x]) Β Β Β Β Β Β Β Β return dp[i][j][x]; Β
Β Β Β Β v[i][j][x] = 1; Β
Β Β Β Β // Recurrence relation Β Β Β Β dp[i][j][x] = countWays(i + 1, j, x, arr) Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β + countWays(i, j + 1, x, arr); Β
Β Β Β Β return dp[i][j][x]; } Β
// Driver code var arr = [ [ 1, 2, 1 ], Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β [ 1, 1, 0 ], Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β [ 2, 1, 1 ] ]; document.write( countWays(0, 0, arr[0][0], arr)); Β
Β
</script> |
1
Β
Time Complexity: O(n2)
Auxiliary Space: O(n4 * maxV)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!