Count of ways to traverse a Matrix and return to origin in K steps
Last Updated :
16 Jan, 2024
Given three integers N, M and K, where N and M are the dimensions of the matrix and K is the maximum possible steps, the task is to count the number ways to start from (0, 0) and return traversing the matrix by using K steps only.
Note: In each step, one can move up, down, left, right, or stay at the current position. The answer could be large, so print the answer modulo 109 + 7
Examples:
Input: N = 2, M = 2, K = 2
Output: 3
Explanation:
Three ways are:
1)Stay, Stay.
2)Up, Down
3)Right, Left
Input: N = 3, M = 3, K = 4
Output: 23
Approach: The problem can also be solved using Memoization technique. Follow the steps below to solve the problem:
- Starting from position (0, 0), recursively call every possible position and decrease the value of steps by 1.
- Create a 3D array of size N * M * K ( DP[N][M][S] )
Possible ways for each step
can be calculated by:
DP[i][j][k]
= Recursion(i+1, j, k-1) +
Recursion(i-1, j, k-1) +
Recursion(i, j-1, k-1) +
Recursion(i, j+1, k-1) +
Recursion(i, j, k-1).
With base condition returning 0,
whenever
i >= l or i = b or j < 0 or k < 0.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
#define MOD 1000000007
long long dp[101][101][101];
int N, M, K;
void Initialize()
{
for ( int i = 0; i <= 100; i++)
for ( int j = 0; j <= 100; j++)
for ( int z = 0; z <= 100; z++)
dp[i][j][z] = -1;
}
int CountWays( int i, int j, int k)
{
if (i >= N || i < 0
|| j >= M || j < 0 || k < 0)
return 0;
if (i == 0 && j == 0
&& k == 0)
return 1;
if (dp[i][j][k] != -1)
return dp[i][j][k];
else
dp[i][j][k]
= (CountWays(i + 1, j, k - 1) % MOD
+ CountWays(i - 1, j, k - 1) % MOD
+ CountWays(i, j - 1, k - 1) % MOD
+ CountWays(i, j + 1, k - 1) % MOD
+ CountWays(i, j, k - 1) % MOD)
% MOD;
return dp[i][j][k];
}
int main()
{
N = 3;
M = 3;
K = 4;
Initialize();
cout << CountWays(0, 0, K)
<< "\n" ;
return 0;
}
|
Java
class GFG{
static int [][][] dp = new int [ 101 ][ 101 ][ 101 ];
static int N, M, K;
static int MOD = 1000000007 ;
public static void Initialize()
{
for ( int i = 0 ; i <= 100 ; i++)
for ( int j = 0 ; j <= 100 ; j++)
for ( int z = 0 ; z <= 100 ; z++)
dp[i][j][z] = - 1 ;
}
public static int CountWays( int i, int j, int k)
{
if (i >= N || i < 0 ||
j >= M || j < 0 || k < 0 )
return 0 ;
if (i == 0 && j == 0 && k == 0 )
return 1 ;
if (dp[i][j][k] != - 1 )
return dp[i][j][k];
else
dp[i][j][k] = (CountWays(i + 1 , j, k - 1 ) % MOD +
CountWays(i - 1 , j, k - 1 ) % MOD +
CountWays(i, j - 1 , k - 1 ) % MOD +
CountWays(i, j + 1 , k - 1 ) % MOD +
CountWays(i, j, k - 1 ) % MOD) % MOD;
return dp[i][j][k];
}
public static void main(String[] args)
{
N = 3 ;
M = 3 ;
K = 4 ;
Initialize();
System.out.println(CountWays( 0 , 0 , K));
}
}
|
Python3
MOD = 1000000007
dp = [[[ 0 for i in range ( 101 )]
for i in range ( 101 )]
for i in range ( 101 )]
N, M, K = 0 , 0 , 0
def Initialize():
for i in range ( 101 ):
for j in range ( 101 ):
for z in range ( 101 ):
dp[i][j][z] = - 1
def CountWays(i, j, k):
if (i > = N or i < 0 or
j > = M or j < 0 or k < 0 ):
return 0
if (i = = 0 and j = = 0 and k = = 0 ):
return 1
if (dp[i][j][k] ! = - 1 ):
return dp[i][j][k]
else :
dp[i][j][k] = (CountWays(i + 1 , j, k - 1 ) % MOD +
CountWays(i - 1 , j, k - 1 ) % MOD +
CountWays(i, j - 1 , k - 1 ) % MOD +
CountWays(i, j + 1 , k - 1 ) % MOD +
CountWays(i, j, k - 1 ) % MOD) % MOD
return dp[i][j][k]
if __name__ = = '__main__' :
N = 3
M = 3
K = 4
Initialize()
print (CountWays( 0 , 0 , K))
|
C#
using System;
class GFG{
static int [,,] dp = new int [101, 101, 101];
static int N, M, K;
static int MOD = 1000000007;
public static void Initialize()
{
for ( int i = 0; i <= 100; i++)
for ( int j = 0; j <= 100; j++)
for ( int z = 0; z <= 100; z++)
dp[i, j, z] = -1;
}
public static int CountWays( int i, int j, int k)
{
if (i >= N || i < 0 ||
j >= M || j < 0 || k < 0)
return 0;
if (i == 0 && j == 0 && k == 0)
return 1;
if (dp[i, j, k] != -1)
return dp[i, j, k];
else
dp[i, j, k] = (CountWays(i + 1, j, k - 1) % MOD +
CountWays(i - 1, j, k - 1) % MOD +
CountWays(i, j - 1, k - 1) % MOD +
CountWays(i, j + 1, k - 1) % MOD +
CountWays(i, j, k - 1) % MOD) % MOD;
return dp[i, j, k];
}
public static void Main(String[] args)
{
N = 3;
M = 3;
K = 4;
Initialize();
Console.WriteLine(CountWays(0, 0, K));
}
}
|
Javascript
<script>
var MOD = 1000000007;
var dp = Array.from(Array(101), ()=>Array(101));
for ( var i =0; i<101; i++)
for ( var j =0; j<101; j++)
dp[i][j] = new Array(101).fill(-1);
var N, M, K;
function CountWays(i, j, k)
{
if (i >= N || i < 0
|| j >= M || j < 0 || k < 0)
return 0;
if (i == 0 && j == 0
&& k == 0)
return 1;
if (dp[i][j][k] != -1)
return dp[i][j][k];
else
dp[i][j][k]
= (CountWays(i + 1, j, k - 1) % MOD
+ CountWays(i - 1, j, k - 1) % MOD
+ CountWays(i, j - 1, k - 1) % MOD
+ CountWays(i, j + 1, k - 1) % MOD
+ CountWays(i, j, k - 1) % MOD)
% MOD;
return dp[i][j][k];
}
N = 3;
M = 3;
K = 4;
document.write( CountWays(0, 0, K))
</script>
|
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.
Steps to solve this problem :
- Create a 3D DP to store the solution of the subproblems and initialize it with 0.
- Initialize the DP with base cases dp[0][0][0] = 1.
- Now Iterate over subproblems to get the value of current problem form previous computation of subproblems stored in DP
- Return the final solution stored in dp[0][0][k].
Implementation :
C++
#include <bits/stdc++.h>
using namespace std;
#define MOD 1000000007
int CountWays( int n, int m, int k)
{
int dp[k+1][n+1][m+1];
memset (dp, 0, sizeof (dp));
dp[0][0][0] = 1;
for ( int l = 1; l <= k; l++) {
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < m; j++) {
dp[i][j][l] = ((i > 0 ? dp[i - 1][j][l - 1] : 0)
+ (i < n - 1 ? dp[i + 1][j][l - 1] : 0)
+ (j > 0 ? dp[i][j - 1][l - 1] : 0)
+ (j < m - 1 ? dp[i][j + 1][l - 1] : 0)
+ dp[i][j][l - 1]) % MOD;
}
}
}
return dp[0][0][k];
}
int main()
{
int N = 3;
int M = 3;
int K = 4;
cout << CountWays(N, M, K) << "\n" ;
return 0;
}
|
Java
import java.util.Arrays;
public class Main {
static final int MOD = 1000000007 ;
static int countWays( int n, int m, int k) {
int [][][] dp = new int [k + 1 ][n + 1 ][m + 1 ];
for ( int [][] matrix : dp) {
for ( int [] row : matrix) {
Arrays.fill(row, 0 );
}
}
dp[ 0 ][ 0 ][ 0 ] = 1 ;
for ( int l = 1 ; l <= k; l++) {
for ( int i = 0 ; i < n; i++) {
for ( int j = 0 ; j < m; j++) {
dp[l][i][j] = ((i > 0 ? dp[l - 1 ][i - 1 ][j] : 0 )
+ (i < n - 1 ? dp[l - 1 ][i + 1 ][j] : 0 )
+ (j > 0 ? dp[l - 1 ][i][j - 1 ] : 0 )
+ (j < m - 1 ? dp[l - 1 ][i][j + 1 ] : 0 )
+ dp[l - 1 ][i][j]) % MOD;
}
}
}
return dp[k][ 0 ][ 0 ];
}
public static void main(String[] args) {
int N = 3 ;
int M = 3 ;
int K = 4 ;
System.out.println(countWays(N, M, K));
}
}
|
Python3
MOD = 1000000007
def CountWays(n, m, k):
dp = [[[ 0 for i in range (m + 1 )] for j in range (n + 1 )] for k in range (k + 1 )]
dp[ 0 ][ 0 ][ 0 ] = 1
for l in range ( 1 , k + 1 ):
for i in range (n):
for j in range (m):
dp[l][i][j] = ((dp[l - 1 ][i - 1 ][j] if i > 0 else 0 )
+ (dp[l - 1 ][i + 1 ][j] if i < n - 1 else 0 )
+ (dp[l - 1 ][i][j - 1 ] if j > 0 else 0 )
+ (dp[l - 1 ][i][j + 1 ] if j < m - 1 else 0 )
+ dp[l - 1 ][i][j]) % MOD
return dp[k][ 0 ][ 0 ]
if __name__ = = "__main__" :
N = 3
M = 3
K = 4
print (CountWays(N, M, K))
|
C#
using System;
class GFG {
const int MOD = 1000000007;
static int CountWays( int n, int m, int k)
{
int [][][] dp = new int [k + 1][][];
for ( int i = 0; i <= k; i++) {
dp[i] = new int [n + 1][];
for ( int j = 0; j <= n; j++) {
dp[i][j] = new int [m + 1];
}
}
dp[0][0][0] = 1;
for ( int l = 1; l <= k; l++) {
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < m; j++) {
dp[l][i][j]
= ((i > 0 ? dp[l - 1][i - 1][j] : 0)
+ (i < n - 1
? dp[l - 1][i + 1][j]
: 0)
+ (j > 0 ? dp[l - 1][i][j - 1]
: 0)
+ (j < m - 1
? dp[l - 1][i][j + 1]
: 0)
+ dp[l - 1][i][j])
% MOD;
}
}
}
return dp[k][0][0];
}
static void Main( string [] args)
{
int N = 3;
int M = 3;
int K = 4;
Console.WriteLine(CountWays(N, M, K));
}
}
|
Javascript
const MOD = 1000000007;
function CountWays(n, m, k) {
const dp = new Array(k + 1)
.fill( null )
.map(() =>
new Array(n + 1)
.fill( null )
.map(() =>
new Array(m + 1).fill(0)
)
);
dp[0][0][0] = 1;
for (let l = 1; l <= k; l++) {
for (let i = 0; i < n; i++) {
for (let j = 0; j < m; j++) {
dp[l][i][j] = (
(i > 0 ? dp[l - 1][i - 1][j] : 0) +
(i < n - 1 ? dp[l - 1][i + 1][j] : 0) +
(j > 0 ? dp[l - 1][i][j - 1] : 0) +
(j < m - 1 ? dp[l - 1][i][j + 1] : 0) +
dp[l - 1][i][j]
) % MOD;
}
}
}
return dp[k][0][0];
}
const N = 3;
const M = 3;
const K = 4;
console.log(CountWays(N, M, K));
|
Time Complexity : O(N*K*M)
Auxiliary Space : O(N*K*M)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...