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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 

chevron_right


Output:

1


My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.