Number of ways to reach the end of matrix with non-zero AND value
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++
#include <bits/stdc++.h>
#define n 3
#define maxV 20
using namespace std;
int dp[n][n][maxV];
int v[n][n][maxV];
int countWays( int i, int j, int x, int arr[][n])
{
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 (v[i][j][x])
return dp[i][j][x];
v[i][j][x] = 1;
dp[i][j][x] = countWays(i + 1, j, x, arr)
+ countWays(i, j + 1, x, arr);
return dp[i][j][x];
}
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
class GFG {
static int n = 3 ;
static int maxV = 20 ;
static int [][][] dp = new int [n][n][maxV];
static int [][][] v = new int [n][n][maxV];
static int countWays( int i, int j,
int x, int arr[][])
{
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 (v[i][j][x] == 1 ) {
return dp[i][j][x];
}
v[i][j][x] = 1 ;
dp[i][j][x] = countWays(i + 1 , j, x, arr)
+ countWays(i, j + 1 , x, arr);
return dp[i][j][x];
}
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));
}
}
|
Python3
n = 3
maxV = 20
dp = [[[ 0 for i in range (maxV)]
for i in range (n)]
for i in range (n)]
v = [[[ 0 for i in range (maxV)]
for i in range (n)]
for i in range (n)]
def countWays(i, j, x, arr):
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 (v[i][j][x]):
return dp[i][j][x]
v[i][j][x] = 1
dp[i][j][x] = countWays(i + 1 , j, x, arr) + \
countWays(i, j + 1 , x, arr);
return dp[i][j][x]
arr = [[ 1 , 2 , 1 ],
[ 1 , 1 , 0 ],
[ 2 , 1 , 1 ]]
print (countWays( 0 , 0 , arr[ 0 ][ 0 ], arr))
|
C#
using System;
class GFG
{
static int n = 3;
static int maxV = 20;
static int [,,] dp = new int [n, n, maxV];
static int [,,] v = new int [n, n, maxV];
static int countWays( int i, int j,
int x, int [,]arr)
{
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 (v[i, j, x] == 1)
{
return dp[i, j, x];
}
v[i, j, x] = 1;
dp[i, j, x] = countWays(i + 1, j, x, arr)
+ countWays(i, j + 1, x, arr);
return dp[i, j, x];
}
public static void Main()
{
int [,]arr = { { 1, 2, 1 },
{ 1, 1, 0 },
{ 2, 1, 1 } };
Console.WriteLine(countWays(0, 0, arr[0,0], arr));
}
}
|
Javascript
<script>
var n = 3;
var maxV = 20;
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);
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 countWays(i, j, x, arr)
{
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 (v[i][j][x])
return dp[i][j][x];
v[i][j][x] = 1;
dp[i][j][x] = countWays(i + 1, j, x, arr)
+ countWays(i, j + 1, x, arr);
return dp[i][j][x];
}
var arr = [ [ 1, 2, 1 ],
[ 1, 1, 0 ],
[ 2, 1, 1 ] ];
document.write( countWays(0, 0, arr[0][0], arr));
</script>
|
Time Complexity: O(n2)
Auxiliary Space: O(n4 * maxV)
Last Updated :
26 Nov, 2021
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...