📜  计算矩阵中达到给定分数的方法数量

📅  最后修改于: 2021-04-23 22:06:19             🧑  作者: Mango

给定一个由非负整数组成的N x N矩阵mat [] [] ,任务是找到从像元(0,0)到像元(N – 1 )达到给定分数M的方法数量。 ,N – 1) ,只需向下(从(i,j)到(i + 1,j))或向右(从(i,j)到(i,j + 1))。每当达到一个单元格(i,j)时,总得分就会由currentScore + mat [i] [j]更新

例子:

方法:可以使用动态编程解决此问题。首先,我们需要确定DP的状态。对于每个单元格(i,j)且数字0≤X≤M ,我们将存储从单元格(0,0)到达该单元格的总数为X的方式数。因此,我们的解决方案将使用3维动态编程,其中两个用于单元格的坐标,另一个用于所需的得分值。
所需的递归关系将是

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
#define n 3
#define MAX 30
  
// To store the states of dp
int dp[n][n][MAX];
  
// To check whether a particular state
// of dp has been solved
bool v[n][n][MAX];
  
// Function to find the ways
// using memoisation
int findCount(int mat[][n], int i, int j, int m)
{
    // Base cases
    if (i == 0 && j == 0) {
        if (m == mat[0][0])
            return 1;
        else
            return 0;
    }
  
    // If required score becomes negative
    if (m < 0)
        return 0;
  
    if (i < 0 || j < 0)
        return 0;
  
    // If current state has been reached before
    if (v[i][j][m])
        return dp[i][j][m];
  
    // Set current state to visited
    v[i][j][m] = true;
  
    dp[i][j][m] = findCount(mat, i - 1, j, m - mat[i][j])
                  + findCount(mat, i, j - 1, m - mat[i][j]);
    return dp[i][j][m];
}
  
// Driver code
int main()
{
    int mat[n][n] = { { 1, 1, 1 },
                      { 1, 1, 1 },
                      { 1, 1, 1 } };
    int m = 5;
    cout << findCount(mat, n - 1, n - 1, m);
  
    return 0;
}


Java
// Java implementation of the approach
class GFG
{
  
static int n = 3;
static int MAX =30;
  
// To store the states of dp
static int dp[][][] = new int[n][n][MAX];
  
// To check whether a particular state
// of dp has been solved
static boolean v[][][] = new boolean[n][n][MAX];
  
// Function to find the ways
// using memoisation
static int findCount(int mat[][], int i, int j, int m)
{
    // Base cases
    if (i == 0 && j == 0) 
    {
        if (m == mat[0][0])
            return 1;
        else
            return 0;
    }
  
    // If required score becomes negative
    if (m < 0)
        return 0;
  
    if (i < 0 || j < 0)
        return 0;
  
    // If current state has been reached before
    if (v[i][j][m])
        return dp[i][j][m];
  
    // Set current state to visited
    v[i][j][m] = true;
  
    dp[i][j][m] = findCount(mat, i - 1, j, m - mat[i][j])
                + findCount(mat, i, j - 1, m - mat[i][j]);
    return dp[i][j][m];
}
  
// Driver code
public static void main(String[] args)
{
    int mat[][] = { { 1, 1, 1 },
                    { 1, 1, 1 },
                    { 1, 1, 1 } };
    int m = 5;
    System.out.println(findCount(mat, n - 1, n - 1, m));
}
}
  
/* This code contributed by PrinciRaj1992 */


Python3
# Python3 implementation of the approach
n = 3
MAX = 60
  
# To store the states of dp
dp = [[[0 for i in range(30)]   
          for i in range(30)]
          for i in range(MAX + 1)]
  
# To check whether a particular state
# of dp has been solved
v = [[[0 for i in range(30)] 
         for i in range(30)]
         for i in range(MAX + 1)]
  
# Function to find the ways
# using memoisation
def findCount(mat, i, j, m):
      
    # Base cases
    if (i == 0 and j == 0):
        if (m == mat[0][0]):
            return 1
        else:
            return 0
  
    # If required score becomes negative
    if (m < 0):
        return 0
  
    if (i < 0 or j < 0):
        return 0
  
    # If current state has been reached before
    if (v[i][j][m] > 0):
        return dp[i][j][m]
  
    # Set current state to visited
    v[i][j][m] = True
  
    dp[i][j][m] = (findCount(mat, i - 1, j, 
                             m - mat[i][j]) + 
                   findCount(mat, i, j - 1, 
                             m - mat[i][j]))
  
    return dp[i][j][m]
  
# Driver code
mat = [ [ 1, 1, 1 ],
        [ 1, 1, 1 ],
        [ 1, 1, 1 ] ]
m = 5
print(findCount(mat, n - 1, n - 1, m))
  
# This code is contributed by mohit kumar


C#
// C# implementation of the approach 
using System;
  
class GFG 
{ 
  
static int n = 3; 
static int MAX = 30; 
  
// To store the states of dp 
static int [,,]dp = new int[n, n, MAX]; 
  
// To check whether a particular state 
// of dp has been solved 
static bool [,,]v = new bool[n, n, MAX]; 
  
// Function to find the ways 
// using memoisation 
static int findCount(int [,]mat, int i,
                          int j, int m) 
{ 
    // Base cases 
    if (i == 0 && j == 0) 
    { 
        if (m == mat[0, 0]) 
            return 1; 
        else
            return 0; 
    } 
  
    // If required score becomes negative 
    if (m < 0) 
        return 0; 
  
    if (i < 0 || j < 0) 
        return 0; 
  
    // If current state has been reached before 
    if (v[i, j, m]) 
        return dp[i, j, m]; 
  
    // Set current state to visited 
    v[i, j, m] = true; 
  
    dp[i, j, m] = findCount(mat, i - 1, j, m - mat[i, j]) + 
                  findCount(mat, i, j - 1, m - mat[i, j]); 
    return dp[i, j, m]; 
} 
  
// Driver code 
public static void Main() 
{ 
    int [,]mat = {{ 1, 1, 1 }, 
                  { 1, 1, 1 }, 
                  { 1, 1, 1 }}; 
    int m = 5; 
    Console.WriteLine(findCount(mat, n - 1, n - 1, m)); 
}
} 
  
// This code is contributed by Ryuga


PHP


输出:
6

时间复杂度: O(N * N * M)