给定一个矩阵,其中每个单元格都有一定数量的硬币。计算使用恰好 k 个硬币从左上角到达右下角的方法数。我们可以从单元格 (i, j) 移动到 (i+1, j) 和 (i, j+1)。
例子:
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
我们强烈建议您在继续解决方案之前单击此处进行练习。
上述问题可以递归定义如下:
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])
下面是上述递归算法的实现。
C++
// A Naive Recursive C++ program
// to count paths with exactly
// 'k' coins
#include
#define R 3
#define C 3
using namespace std;
// Recursive function to count paths with sum k from
// (0, 0) to (m, n)
int pathCountRec(int mat[][C], int m, int n, int k)
{
// Base cases
if (m < 0 || n < 0) return 0;
if (m==0 && n==0) return (k == mat[m][n]);
// (m, n) can be reached either through (m-1, n) or
// through (m, n-1)
return pathCountRec(mat, m-1, n, k-mat[m][n]) +
pathCountRec(mat, m, n-1, k-mat[m][n]);
}
// A wrapper over pathCountRec()
int pathCount(int mat[][C], int k)
{
return pathCountRec(mat, R-1, C-1, k);
}
// Driver program
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
// A Naive Recursive Java program to
// count paths with exactly 'k' coins
class GFG {
static final int R = 3;
static final int C = 3;
// Recursive function to count paths with sum k from
// (0, 0) to (m, n)
static int pathCountRec(int mat[][], int m, int n, int k) {
// Base cases
if (m < 0 || n < 0) {
return 0;
}
if (m == 0 && n == 0 && (k == mat[m][n])) {
return 1;
}
// (m, n) can be reached either through (m-1, n) or
// through (m, n-1)
return pathCountRec(mat, m - 1, n, k - mat[m][n])
+ pathCountRec(mat, m, n - 1, k - mat[m][n]);
}
// A wrapper over pathCountRec()
static int pathCount(int mat[][], int k) {
return pathCountRec(mat, R - 1, C - 1, k);
}
// Driver code
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));
}
}
/* This Java code is contributed by Rajput-Ji*/
Python3
# A Naive Recursive Python program to
# count paths with exactly 'k' coins
R = 3
C = 3
# Recursive function to count paths
# with sum k from (0, 0) to (m, n)
def pathCountRec(mat, m, n, k):
# Base cases
if m < 0 or n < 0:
return 0
elif m == 0 and n == 0:
return k == mat[m][n]
# #(m, n) can be reached either
# through (m-1, n) or through
# (m, n-1)
return (pathCountRec(mat, m-1, n, k-mat[m][n])
+ pathCountRec(mat, m, n-1, k-mat[m][n]))
# A wrapper over pathCountRec()
def pathCount(mat, k):
return pathCountRec(mat, R-1, C-1, k)
# Driver Program
k = 12
mat = [[1, 2, 3],
[4, 6, 5],
[3, 2, 1]]
print(pathCount(mat, k))
# This code is contributed by Shrikant13.
C#
using System;
// A Naive Recursive c# program to
// count paths with exactly 'k' coins
public class GFG
{
public const int R = 3;
public const int C = 3;
// Recursive function to count paths with sum k from
// (0, 0) to (m, n)
public static int pathCountRec(int[][] mat, int m, int n, int k)
{
// Base cases
if (m < 0 || n < 0)
{
return 0;
}
if (m == 0 && n == 0 && (k == mat[m][n]))
{
return 1;
}
// (m, n) can be reached either through (m-1, n) or
// through (m, n-1)
return pathCountRec(mat, m - 1, n, k - mat[m][n])
+ pathCountRec(mat, m, n - 1, k - mat[m][n]);
}
// A wrapper over pathCountRec()
public static int pathCount(int[][] mat, int k)
{
return pathCountRec(mat, R - 1, C - 1, k);
}
// Driver code
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));
}
}
// This code is contributed by Shrikant13
PHP
Javascript
// A Naive Recursive Javascript program
// to count paths with exactly
// 'k' coins
let R = 3;
let C = 3;
// Recursive function to count paths with
// sum k from (0, 0) to (m, n)
function pathCountRec(mat, m, n, k)
{
// Base cases
if (m < 0 || n < 0)
return 0;
if (m == 0 && n == 0)
return (k == mat[m][n]);
// (m, n) can be reached either through (m-1, n) or
// through (m, n-1)
return pathCountRec(mat, m - 1, n, k - mat[m][n]) +
pathCountRec(mat, m, n - 1, k - mat[m][n]);
}
// A wrapper over pathCountRec()
function pathCount(mat, k)
{
return pathCountRec(mat, R - 1, C - 1, k);
}
// Driver code
let k = 12;
let mat = [ [ 1, 2, 3 ],
[ 4, 6, 5 ],
[ 3, 2, 1 ] ];
document.write(pathCount(mat, k));
// This code is contributed by divyesh072019
2
C++
// A Dynamic Programming based C++ program to count paths with
// exactly 'k' coins
#include
#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)
{
// Base cases
if (m < 0 || n < 0) return 0;
if (m==0 && n==0) return (k == mat[m][n]);
// If this subproblem is already solved
if (dp[m][n][k] != -1) return dp[m][n][k];
// (m, n) can be reached either through (m-1, n) or
// through (m, n-1)
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];
}
// This function mainly initializes dp[][][] and calls
// pathCountDPRecDP()
int pathCountDP(int mat[][C], int k)
{
memset(dp, -1, sizeof dp);
return pathCountDPRecDP(mat, R-1, C-1, k);
}
// Driver Program to test above functions
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
// A Dynamic Programming based JAVA program to count paths with
// exactly 'k' coins
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)
{
// Base cases
if (m < 0 || n < 0) return 0;
if (m==0 && n==0) return (k == mat[m][n] ? 1 : 0);
// If this subproblem is already solved
if (dp[m][n][k] != -1) return dp[m][n][k];
// (m, n) can be reached either through (m-1, n) or
// through (m, n-1)
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];
}
// This function mainly initializes dp[][][] and calls
// pathCountDPRecDP()
static int pathCountDP(int [][]mat, int k)
{
for(int i=0;i
Python3
# A Dynamic Programming based Python3 program to
# count paths with exactly 'k' coins
R = 3
C = 3
MAX_K = 1000
def pathCountDPRecDP(mat, m, n, k):
# Base cases
if m < 0 or n < 0:
return 0
elif m == 0 and n == 0:
return k == mat[m][n]
# If this subproblem is already solved
if (dp[m][n][k] != -1):
return dp[m][n][k]
# #(m, n) can be reached either
# through (m-1, n) or through
# (m, n-1)
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]
# A wrapper over pathCountDPRecDP()
def pathCountDP(mat, k):
return pathCountDPRecDP(mat, R - 1, C - 1, k)
# Driver Code
k = 12
# Initialising dp[][][]
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))
# This code is contributed by ashutosh450
C#
// A Dynamic Programming based C# program
// to count paths with exactly 'k' coins
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)
{
// Base cases
if (m < 0 || n < 0) return 0;
if (m == 0 && n == 0)
return (k == mat[m, n] ? 1 : 0);
// If this subproblem is already solved
if (dp[m, n, k] != -1) return dp[m, n, k];
// (m, n) can be reached either through (m-1, n) or
// through (m, n-1)
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];
}
// This function mainly initializes [,]dp[] and
// calls pathCountDPRecDP()
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);
}
// Driver Code
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));
}
}
// This code is contributed by PrinciRaj1992
Javascript
// A Dynamic Programming based javascript program to count paths with
// exactly 'k' coins
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) {
// Base cases
if (m < 0 || n < 0)
return 0;
if (m == 0 && n == 0)
return (k == mat[m][n] ? 1 : 0);
// If this subproblem is already solved
if (dp[m][n][k] != -1)
return dp[m][n][k];
// (m, n) can be reached either through (m-1, n) or
// through (m, n-1)
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];
}
// This function mainly initializes dp and calls
// pathCountDPRecDP()
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);
}
// Driver Program to test above functions
var k = 12;
var mat = [[ 1, 2, 3 ],[ 4, 6, 5 ], [ 3, 2, 1 ] ];
document.write(pathCountDP(mat, k));
// This code contributed by aashish1995
输出:
2
上述解递归的时间复杂度是指数级的。我们可以使用动态规划在伪多项式时间(时间复杂度取决于输入的数值)中解决这个问题。这个想法是使用一个 3 维表 dp[m][n][k] 其中 m 是行号,n 是列号,k 是硬币的数量。下面是基于动态规划的实现。
C++
// A Dynamic Programming based C++ program to count paths with
// exactly 'k' coins
#include
#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)
{
// Base cases
if (m < 0 || n < 0) return 0;
if (m==0 && n==0) return (k == mat[m][n]);
// If this subproblem is already solved
if (dp[m][n][k] != -1) return dp[m][n][k];
// (m, n) can be reached either through (m-1, n) or
// through (m, n-1)
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];
}
// This function mainly initializes dp[][][] and calls
// pathCountDPRecDP()
int pathCountDP(int mat[][C], int k)
{
memset(dp, -1, sizeof dp);
return pathCountDPRecDP(mat, R-1, C-1, k);
}
// Driver Program to test above functions
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
// A Dynamic Programming based JAVA program to count paths with
// exactly 'k' coins
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)
{
// Base cases
if (m < 0 || n < 0) return 0;
if (m==0 && n==0) return (k == mat[m][n] ? 1 : 0);
// If this subproblem is already solved
if (dp[m][n][k] != -1) return dp[m][n][k];
// (m, n) can be reached either through (m-1, n) or
// through (m, n-1)
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];
}
// This function mainly initializes dp[][][] and calls
// pathCountDPRecDP()
static int pathCountDP(int [][]mat, int k)
{
for(int i=0;i
蟒蛇3
# A Dynamic Programming based Python3 program to
# count paths with exactly 'k' coins
R = 3
C = 3
MAX_K = 1000
def pathCountDPRecDP(mat, m, n, k):
# Base cases
if m < 0 or n < 0:
return 0
elif m == 0 and n == 0:
return k == mat[m][n]
# If this subproblem is already solved
if (dp[m][n][k] != -1):
return dp[m][n][k]
# #(m, n) can be reached either
# through (m-1, n) or through
# (m, n-1)
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]
# A wrapper over pathCountDPRecDP()
def pathCountDP(mat, k):
return pathCountDPRecDP(mat, R - 1, C - 1, k)
# Driver Code
k = 12
# Initialising dp[][][]
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))
# This code is contributed by ashutosh450
C#
// A Dynamic Programming based C# program
// to count paths with exactly 'k' coins
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)
{
// Base cases
if (m < 0 || n < 0) return 0;
if (m == 0 && n == 0)
return (k == mat[m, n] ? 1 : 0);
// If this subproblem is already solved
if (dp[m, n, k] != -1) return dp[m, n, k];
// (m, n) can be reached either through (m-1, n) or
// through (m, n-1)
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];
}
// This function mainly initializes [,]dp[] and
// calls pathCountDPRecDP()
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);
}
// Driver Code
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));
}
}
// This code is contributed by PrinciRaj1992
Javascript
// A Dynamic Programming based javascript program to count paths with
// exactly 'k' coins
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) {
// Base cases
if (m < 0 || n < 0)
return 0;
if (m == 0 && n == 0)
return (k == mat[m][n] ? 1 : 0);
// If this subproblem is already solved
if (dp[m][n][k] != -1)
return dp[m][n][k];
// (m, n) can be reached either through (m-1, n) or
// through (m, n-1)
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];
}
// This function mainly initializes dp and calls
// pathCountDPRecDP()
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);
}
// Driver Program to test above functions
var k = 12;
var mat = [[ 1, 2, 3 ],[ 4, 6, 5 ], [ 3, 2, 1 ] ];
document.write(pathCountDP(mat, k));
// This code contributed by aashish1995
输出:
2
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。