📌  相关文章
📜  通过每行取一个元素来检查是否有可能获得给定的总和

📅  最后修改于: 2021-04-29 10:12:14             🧑  作者: Mango

给定N行和M列的二维数组,以及整数K。任务是确定是否有可能从给定数组的每一行中精确地获取一个元素并使总和等于K。

例子:

Input: N = 2, M = 10, K = 5
arr = {{4, 0, 15, 3, 2, 20, 10, 1, 5, 4}, 
      {4, 0, 10, 3, 2, 25, 4, 1, 5, 4}}
Output: YES
Explanation:
Take 2 from first row and 3 from second row.
2 + 3 = 5
So, we can make 5 by taking exactly one element
from each row.

Input:N = 3, M = 5, K = 5
arr = {{4, 3, 4, 5, 4}, 
       {2, 2, 3, 4, 3}, 
       {2, 1, 3, 3, 2}}
Output: NO

方法:可以使用动态编程解决此问题。

  1. 我们可以制作一个N行和K列的二维二进制数组DP [] []。其中DP [i] [j] = 1表示我们可以通过从每一行直到i都取一个元素来使总和等于j。
  2. 因此,我们将从i = [0,N],k = [0,K]迭代数组,并检查当前sum(k)是否存在。
  3. 如果当前总和存在,那么我们将遍历该列,并为每个小于或等于K的总和更新数组。

下面是上述方法的实现

C++
// C++ implementation to find
// whether is it possible to
// make sum equal to K
#include 
using namespace std;
  
// Function that prints whether is it
// possible to make sum equal to K
void PossibleSum(int n, int m,
              vector > v, 
              int k)
{
    int dp[n + 1][k + 1] = { 0 };
  
    // Base case
    dp[0][0] = 1;
  
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j <= k; j++)
        {
            // Condition if we can make 
            // sum equal to current column
            // by using above rows
            if (dp[i][j] == 1)
            {
                // Iterate through current 
                // column and check whether
                // we can make sum less than
                // or equal to k
                for (int d = 0; d < m; d++)
                {
                    if ((j + v[i][d]) <= k)
                    {
                        dp[i + 1][j + v[i][d]] = 1;
                    }
                }
            }
        }
    }
  
    // Printing whether is it
    // possible or not
    if (dp[n][k] == 1)
        cout << "YES\n";
    else
        cout << "NO\n";
}
  
// Driver Code
int main()
{
    int N = 2, M = 10, K = 5;
  
    vector > arr = { { 4, 0, 15, 3, 2, 
                                  20, 10, 1, 5, 4 },
                                 { 4, 0, 10, 3, 2,
                                  25, 4, 1, 5, 4 } };
  
    PossibleSum(N, M, arr, K);
  
    return 0;
}


Java
// Java implementation to find 
// whether is it possible to 
// make sum equal to K
import java.io.*; 
import java.util.*; 
  
class GFG { 
      
// Function that prints whether is it 
// possible to make sum equal to K 
static void PossibleSum(int n, int m, 
                        int[][] v, int k) 
{ 
    int[][] dp = new int[n + 1][k + 1];
  
    // Base case 
    dp[0][0] = 1; 
  
    for(int i = 0; i < n; i++) 
    { 
       for(int j = 0; j <= k; j++) 
       { 
             
          // Condition if we can make 
          // sum equal to current column 
          // by using above rows 
          if (dp[i][j] == 1) 
          { 
                
              // Iterate through current 
              // column and check whether 
              // we can make sum less than 
              // or equal to k 
              for(int d = 0; d < m; d++) 
              { 
                 if ((j + v[i][d]) <= k) 
                 { 
                     dp[i + 1][j + v[i][d]] = 1; 
                 }
              } 
          } 
       } 
    } 
      
    // Printing whether is it 
    // possible or not 
    if (dp[n][k] == 1) 
        System.out.println("YES"); 
    else
        System.out.println("NO");
}
  
// Driver code 
public static void main(String[] args) 
{ 
    int N = 2, M = 10, K = 5; 
    int[][] arr = new int[][]{ { 4, 0, 15, 3, 2, 
                                20, 10, 1, 5, 4 }, 
                               { 4, 0, 10, 3, 2,
                                25, 4, 1, 5, 4 } };
    PossibleSum(N, M, arr, K);
} 
} 
  
// This code is contributed by coder001


Python3
# Python3 implementation to find 
# whether is it possible to 
# make sum equal to K 
  
# Function that prints whether is it 
# possible to make sum equal to K 
def PossibleSum(n, m, v, k): 
      
    dp = [[0] * (k + 1) for i in range(n + 1)] 
      
    # Base case 
    dp[0][0] = 1
  
    for i in range(n): 
        for j in range(k + 1): 
  
            # Condition if we can make 
            # sum equal to current column 
            # by using above rows 
            if dp[i][j] == 1: 
  
                # Iterate through current 
                # column and check whether 
                # we can make sum less than 
                # or equal to k 
                for d in range(m): 
                    if (j + v[i][d]) <= k: 
                        dp[i + 1][j + v[i][d]] = 1
  
    # Printing whether is it 
    # possible or not 
    if dp[n][k] == 1: 
        print("YES") 
    else: 
        print("NO") 
  
# Driver Code 
N = 2
M = 10
K = 5
arr = [ [ 4, 0, 15, 3, 2, 
         20, 10, 1, 5, 4 ], 
        [ 4, 0, 10, 3, 2, 
          25, 4, 1, 5, 4 ] ] 
  
PossibleSum(N, M, arr, K) 
  
# This code is contributed by divyamohan123


C#
// C# implementation to find 
// whether is it possible to 
// make sum equal to K
using System;
class GFG{ 
      
// Function that prints whether is it 
// possible to make sum equal to K 
static void PossibleSum(int n, int m, 
                        int[,] v, int k) 
{ 
    int[,] dp = new int[n + 1, k + 1];
  
    // Base case 
    dp[0, 0] = 1; 
  
    for(int i = 0; i < n; i++) 
    { 
        for(int j = 0; j <= k; j++) 
        { 
                  
            // Condition if we can make 
            // sum equal to current column 
            // by using above rows 
            if (dp[i, j] == 1) 
            { 
                      
                // Iterate through current 
                // column and check whether 
                // we can make sum less than 
                // or equal to k 
                for(int d = 0; d < m; d++) 
                { 
                    if ((j + v[i, d]) <= k) 
                    { 
                        dp[i + 1, j + v[i, d]] = 1; 
                    }
                } 
            } 
        } 
    } 
      
    // Printing whether is it 
    // possible or not 
    if (dp[n, k] == 1) 
        Console.WriteLine("YES"); 
    else
        Console.WriteLine("NO");
}
  
// Driver code 
public static void Main(String[] args) 
{ 
    int N = 2, M = 10, K = 5; 
    int[,] arr = new int[,]{ { 4, 0, 15, 3, 2, 
                              20, 10, 1, 5, 4 }, 
                             { 4, 0, 10, 3, 2,
                              25, 4, 1, 5, 4 } };
    PossibleSum(N, M, arr, K);
} 
} 
  
// This code is contributed by 29AjayKumar


输出:
YES

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