Given a matrix where every cell has some number of coins. Count number of ways to reach bottom right from top left with exactly k coins. We can move to (i+1, j) and (i, j+1) from a cell (i, j).
Example:
Input: k = 12
mat[][] = { {1, 2, 3},
{4, 6, 5},
{3, 2, 1}
};
Output: 2
There are two paths with 12 coins
1 -> 2 -> 6 -> 2 -> 1
1 -> 2 -> 3 -> 5 -> 1
The above problem can be recursively defined as below:
pathCount(m, n, k): Number of paths to reach mat[m][n] from mat[0][0]
with exactly k coins
If (m == 0 and n == 0)
return 1 if mat[0][0] == k else return 0
Else:
pathCount(m, n, k) = pathCount(m-1, n, k - mat[m][n]) +
pathCount(m, n-1, k - mat[m][n])
Below is the implementation of above recursive algorithm.
C++14
#include <bits/stdc++.h>
#define R 3
#define C 3
using namespace std;
int pathCountRec( int mat[][C], int m, int n, int k)
{
if (m < 0 || n < 0 || k < 0) return 0;
if (m==0 && n==0) return (k == mat[m][n]);
return pathCountRec(mat, m-1, n, k-mat[m][n]) +
pathCountRec(mat, m, n-1, k-mat[m][n]);
}
int pathCount( int mat[][C], int k)
{
return pathCountRec(mat, R-1, C-1, k);
}
int main()
{
int k = 12;
int mat[R][C] = { {1, 2, 3},
{4, 6, 5},
{3, 2, 1}
};
cout << pathCount(mat, k);
return 0;
}
|
Java
class GFG {
static final int R = 3 ;
static final int C = 3 ;
static int pathCountRec( int mat[][], int m, int n, int k) {
if (m < 0 || n < 0 || k < 0 ) {
return 0 ;
}
if (m == 0 && n == 0 && (k == mat[m][n])) {
return 1 ;
}
return pathCountRec(mat, m - 1 , n, k - mat[m][n])
+ pathCountRec(mat, m, n - 1 , k - mat[m][n]);
}
static int pathCount( int mat[][], int k) {
return pathCountRec(mat, R - 1 , C - 1 , k);
}
public static void main(String[] args) {
int k = 12 ;
int mat[][] = {{ 1 , 2 , 3 },
{ 4 , 6 , 5 },
{ 3 , 2 , 1 }
};
System.out.println(pathCount(mat, k));
}
}
|
Python3
R = 3
C = 3
def pathCountRec(mat, m, n, k):
if m < 0 or n < 0 or k < 0 :
return 0
elif m = = 0 and n = = 0 :
return k = = mat[m][n]
return (pathCountRec(mat, m - 1 , n, k - mat[m][n])
+ pathCountRec(mat, m, n - 1 , k - mat[m][n]))
def pathCount(mat, k):
return pathCountRec(mat, R - 1 , C - 1 , k)
k = 12
mat = [[ 1 , 2 , 3 ],
[ 4 , 6 , 5 ],
[ 3 , 2 , 1 ]]
print (pathCount(mat, k))
|
C#
using System;
public class GFG
{
public const int R = 3;
public const int C = 3;
public static int pathCountRec( int [][] mat, int m, int n, int k)
{
if (m < 0 || n < 0 || k < 0)
{
return 0;
}
if (m == 0 && n == 0 && (k == mat[m][n]))
{
return 1;
}
return pathCountRec(mat, m - 1, n, k - mat[m][n])
+ pathCountRec(mat, m, n - 1, k - mat[m][n]);
}
public static int pathCount( int [][] mat, int k)
{
return pathCountRec(mat, R - 1, C - 1, k);
}
public static void Main( string [] args)
{
int k = 12;
int [][] mat = new int [][]
{
new int [] {1, 2, 3},
new int [] {4, 6, 5},
new int [] {3, 2, 1}
};
Console.WriteLine(pathCount(mat, k));
}
}
|
PHP
<?php
$R = 3;
$C = 3;
function pathCountRec( $mat , $m , $n , $k )
{
if ( $m < 0 or $n < 0 or $k < 0)
return 0;
if ( $m == 0 and $n == 0)
return ( $k == $mat [ $m ][ $n ]);
return pathCountRec( $mat , $m - 1,
$n , $k - $mat [ $m ][ $n ])
+ pathCountRec( $mat , $m ,
$n - 1, $k - $mat [ $m ][ $n ]);
}
function pathCount( $mat , $k )
{
global $R , $C ;
return pathCountRec( $mat , $R -1,
$C -1, $k );
}
$k = 12;
$mat = array ( array (1, 2, 3),
array (4, 6, 5),
array (3, 2, 1) );
echo pathCount( $mat , $k );
?>
|
Javascript
<script>
let R = 3;
let C = 3;
function pathCountRec(mat, m, n, k)
{
if (m < 0 || n < 0 || k < 0)
return 0;
if (m == 0 && n == 0)
return (k == mat[m][n]);
return pathCountRec(mat, m - 1, n, k - mat[m][n]) +
pathCountRec(mat, m, n - 1, k - mat[m][n]);
}
function pathCount(mat, k)
{
return pathCountRec(mat, R - 1, C - 1, k);
}
let k = 12;
let mat = [ [ 1, 2, 3 ],
[ 4, 6, 5 ],
[ 3, 2, 1 ] ];
document.write(pathCount(mat, k));
</script>
|
Time Complexity: O(2m+n)
Auxiliary Space: O(m*n), since m*n extra space has been taken.
The time complexity of above solution recursive is exponential. We can solve this problem in Pseudo Polynomial Time (time complexity is dependent on numeric value of input) using Dynamic Programming. The idea is to use a 3 dimensional table dp[m][n][k] where m is row number, n is column number and k is number of coins. Below is Dynamic Programming based the implementation.
C++14
#include <bits/stdc++.h>
#define R 3
#define C 3
#define MAX_K 1000
using namespace std;
int dp[R][C][MAX_K];
int pathCountDPRecDP( int mat[][C], int m, int n, int k)
{
if (m < 0 || n < 0 || k < 0) return 0;
if (m==0 && n==0) return (k == mat[m][n]);
if (dp[m][n][k] != -1) return dp[m][n][k];
dp[m][n][k] = pathCountDPRecDP(mat, m-1, n, k-mat[m][n]) +
pathCountDPRecDP(mat, m, n-1, k-mat[m][n]);
return dp[m][n][k];
}
int pathCountDP( int mat[][C], int k)
{
memset (dp, -1, sizeof dp);
return pathCountDPRecDP(mat, R-1, C-1, k);
}
int main()
{
int k = 12;
int mat[R][C] = { {1, 2, 3},
{4, 6, 5},
{3, 2, 1}
};
cout << pathCountDP(mat, k);
return 0;
}
|
Java
class GFG {
static final int R = 3 ;
static final int C = 3 ;
static final int MAX_K = 100 ;
static int [][][] dp = new int [R][C][MAX_K];
static int pathCountDPRecDP( int [][] mat, int m, int n,
int k)
{
if (m < 0 || n < 0 || k < 0 )
return 0 ;
if (m == 0 && n == 0 )
return (k == mat[m][n] ? 1 : 0 );
if (dp[m][n][k] != - 1 )
return dp[m][n][k];
dp[m][n][k]
= pathCountDPRecDP(mat, m - 1 , n, k - mat[m][n])
+ pathCountDPRecDP(mat, m, n - 1 ,
k - mat[m][n]);
return dp[m][n][k];
}
static int pathCountDP( int [][] mat, int k)
{
for ( int i = 0 ; i < R; i++)
for ( int j = 0 ; j < C; j++)
for ( int l = 0 ; l < MAX_K; l++)
dp[i][j][l] = - 1 ;
return pathCountDPRecDP(mat, R - 1 , C - 1 , k);
}
public static void main(String[] args)
{
int k = 12 ;
int [][] mat = new int [][] { new int [] { 1 , 2 , 3 },
new int [] { 4 , 6 , 5 },
new int [] { 3 , 2 , 1 } };
System.out.println(pathCountDP(mat, k));
}
}
|
Python3
R = 3
C = 3
MAX_K = 1000
def pathCountDPRecDP(mat, m, n, k):
if m < 0 or n < 0 or k < 0 :
return 0
elif m = = 0 and n = = 0 :
return k = = mat[m][n]
if (dp[m][n][k] ! = - 1 ):
return dp[m][n][k]
dp[m][n][k] = (pathCountDPRecDP(mat, m - 1 , n, k - mat[m][n]) +
pathCountDPRecDP(mat, m, n - 1 , k - mat[m][n]))
return dp[m][n][k]
def pathCountDP(mat, k):
return pathCountDPRecDP(mat, R - 1 , C - 1 , k)
k = 12
dp = [[ [ - 1 for col in range (MAX_K)]
for col in range (C)]
for row in range (R)]
mat = [[ 1 , 2 , 3 ],
[ 4 , 6 , 5 ],
[ 3 , 2 , 1 ]]
print (pathCountDP(mat, k))
|
C#
using System;
class GFG
{
static readonly int R = 3;
static readonly int C = 3;
static readonly int MAX_K = 100;
static int [,,]dp = new int [R, C, MAX_K];
static int pathCountDPRecDP( int [,]mat, int m,
int n, int k)
{
if (m < 0 || n < 0 || k < 0) return 0;
if (m == 0 && n == 0)
return (k == mat[m, n] ? 1 : 0);
if (dp[m, n, k] != -1) return dp[m, n, k];
dp[m, n, k] = pathCountDPRecDP(mat, m - 1, n, k - mat[m, n]) +
pathCountDPRecDP(mat, m, n - 1, k - mat[m, n]);
return dp[m, n, k];
}
static int pathCountDP( int [,]mat, int k)
{
for ( int i = 0; i < R; i++)
for ( int j = 0; j < C; j++)
for ( int l = 0; l < MAX_K; l++)
dp[i, j, l] = -1;
return pathCountDPRecDP(mat, R - 1, C - 1, k);
}
public static void Main(String []args)
{
int k = 12;
int [,] mat = { {1, 2, 3},
{4, 6, 5},
{3, 2, 1}};
Console.WriteLine(pathCountDP(mat, k));
}
}
|
Javascript
<script>
var R = 3;
var C = 3;
var MAX_K = 100;
var dp = Array(R).fill().map(()=>Array(C).fill().map(()=>Array(MAX_K).fill(0)));
function pathCountDPRecDP(mat , m , n , k) {
if (m < 0 || n < 0 || k < 0)
return 0;
if (m == 0 && n == 0)
return (k == mat[m][n] ? 1 : 0);
if (dp[m][n][k] != -1)
return dp[m][n][k];
dp[m][n][k] = pathCountDPRecDP(mat, m - 1, n, k - mat[m][n]) + pathCountDPRecDP(mat, m, n - 1, k - mat[m][n]);
return dp[m][n][k];
}
function pathCountDP(mat , k) {
for (i = 0; i < R; i++)
for (j = 0; j < C; j++)
for (l = 0; l < MAX_K; l++)
dp[i][j][l] = -1;
return pathCountDPRecDP(mat, R - 1, C - 1, k);
}
var k = 12;
var mat = [[ 1, 2, 3 ],[ 4, 6, 5 ], [ 3, 2, 1 ] ];
document.write(pathCountDP(mat, k));
</script>
|
Time complexity of this solution is O(m*n*k).
Auxiliary Space: O(m*n*k)
Feeling lost in the world of random DSA topics, wasting time without progress? It’s time for a change! Join our DSA course, where we’ll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!