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



Improved By : Rajput-Ji, AnkitRai01