给定一个矩阵,其中每个单元格都有一定数量的硬币。数一数从左上角到右下角的方法,精确到k个硬币。我们可以从一个单元(i,j)移动到(i+1,j)和(i,j+1)。
null
例子:
Input: k = 12 mat[][] = { {1, 2, 3}, {4, 6, 5}, {3, 2, 1} };Output: 2There are two paths with 12 coins1 -> 2 -> 6 -> 2 -> 11 -> 2 -> 3 -> 5 -> 1
我们强烈建议您在继续解决方案之前单击此处并进行练习。
上述问题可递归定义如下:
pathCount(m, n, k): Number of paths to reach mat[m][n] from mat[0][0] with exactly k coinsIf (m == 0 and n == 0) return 1 if mat[0][0] == k else return 0Else: 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 <bits/stdc++.h> #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 else if 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
<?php // A Naive Recursive PHP 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) function pathCountRec( $mat , $m , $n , $k ) { // Base cases if ( $m < 0 or $n < 0) return 0; if ( $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() function pathCount( $mat , $k ) { global $R , $C ; return pathCountRec( $mat , $R -1, $C -1, $k ); } // Driver program $k = 12; $mat = array ( array (1, 2, 3), array (4, 6, 5), array (3, 2, 1) ); echo pathCount( $mat , $k ); // This code is contributed by anuj_67. ?> |
Javascript
<script> // 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 </script> |
输出:
2
上述解的时间复杂度是指数的。我们可以在短期内解决这个问题 伪多项式时间 (时间复杂度取决于输入的数值)使用动态规划。这个想法是使用一个三维表dp[m][n][k],其中m是行数,n是列数,k是硬币数。下面是基于动态规划的实现。
C++
// A Dynamic Programming based C++ program to count paths with // exactly 'k' coins #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) { // 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<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 Program to test above functions 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)); } } // This code is contributed by ihritik |
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 else if 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
<script> // 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 </script> |
输出:
2
该解的时间复杂度为O(m*n*k)。 感谢Gaurav Ahirwar提出上述解决方案。 如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写评论
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END