给定一个矩阵,其中每个单元都有一定数量的硬币。用正确的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
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
输出:
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
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
输出:
2