📜  总和可被 m 整除的子集

📅  最后修改于: 2021-09-22 10:13:23             🧑  作者: Mango

给定一组非负的不同整数和一个值 m,确定是否存在给定集合的子集,其总和可被 m 整除。
输入约束
集合的大小,即,n <= 1000000,m <= 1000
例子:

Input : arr[] = {3, 1, 7, 5};
        m = 6;
Output : YES

Input : arr[] = {1, 6};
        m = 5;
Output : NO

这个问题是子集求和问题的一个变体。在子集和问题中,我们检查给定的和子集是否存在,这里我们需要查找是否存在某个总和可被 m 整除的子集。看到输入约束,看起来典型的 DP 解决方案将在 O(nm) 时间内工作。但是在竞争性编程的紧迫时间限制下,该解决方案可能会奏效。 DP 表的辅助空间也很高,但这里有一个问题。
如果n > m总会有一个总和能被 m 整除的子集(这很容易用鸽巢原理证明)。所以我们只需要处理n <= m 的情况
对于n <= m,我们创建一个布尔 DP 表,该表将存储从 0 到 m-1 的每个值的状态,这些值是迄今为止遇到的可能子集和(模 m)。
现在我们循环遍历给定数组 arr[] 的每个元素,并添加具有 DP[j] = true 的 (modulo m) j,并将所有此类 (j+arr[i])%m 可能的子集总和存储在一个布尔数组 temp,在 j 迭代结束时,我们用 temp 更新 DP 表。此外,我们将 arr[i] 添加到 DP 即.. DP[arr[i]%m] = true。
最后,如果 DP[0] 为真,则表示 YES 存在一个总和可被 m 整除的子集,否则为 NO。

C++
// C++ program to check if there is a subset
// with sum divisible by m.
#include 
using namespace std;
 
// Returns true if there is a subset
// of arr[] with sum divisible by m
bool modularSum(int arr[], int n, int m)
{
    if (n > m)
        return true;
 
    // This array will keep track of all
    // the possible sum (after modulo m)
    // which can be made using subsets of arr[]
    // initialising boolean array with all false
    bool DP[m];
    memset(DP, false, m);
 
    // we'll loop through all the elements of arr[]
    for (int i=0; i


Java
// Java program to check if there is a subset
// with sum divisible by m.
import java.util.Arrays;
 
class GFG {
     
    // Returns true if there is a subset
    // of arr[] with sum divisible by m
    static boolean modularSum(int arr[],
                                int n, int m)
    {
        if (n > m)
            return true;
     
        // This array will keep track of all
        // the possible sum (after modulo m)
        // which can be made using subsets of arr[]
        // initialising boolean array with all false
        boolean DP[]=new boolean[m];
         
        Arrays.fill(DP, false);
     
        // we'll loop through all the elements
        // of arr[]
        for (int i = 0; i < n; i++)
        {
             
            // anytime we encounter a sum divisible
            // by m, we are done
            if (DP[0])
                return true;
     
            // To store all the new encountered sum
            // (after modulo). It is used to make
            // sure that arr[i] is added only to
            // those entries for which DP[j]
            // was true before current iteration.
            boolean temp[] = new boolean[m];
            Arrays.fill(temp, false);
     
            // For each element of arr[], we loop
            // through all elements of DP table
            // from 1 to m and we add current
            // element i. e., arr[i] to all those
            // elements which are true in DP table
            for (int j = 0; j < m; j++)
            {
                 
                // if an element is true in
                // DP table
                if (DP[j] == true)
                {
                    if (DP[(j + arr[i]) % m] == false)
     
                        // We update it in temp and update
                        // to DP once loop of j is over
                        temp[(j + arr[i]) % m] = true;
                }
            }
     
            // Updating all the elements of temp
            // to DP table since iteration over
            // j is over
            for (int j = 0; j < m; j++)
                if (temp[j])
                    DP[j] = true;
     
     
            // Also since arr[i] is a single
            // element subset, arr[i]%m is one
            // of the possible sum
            DP[arr[i] % m] = true;
        }
     
        return DP[0];
    }
     
    //driver code
    public static void main(String arg[])
    {
        int arr[] = {1, 7};
        int n = arr.length;
        int m = 5;
     
        if(modularSum(arr, n, m))
            System.out.print("YES\n");
        else
            System.out.print("NO\n");
    }
}
 
//This code is contributed by Anant Agarwal.


Python3
# Python3 program to check if there is
# a subset with sum divisible by m.
 
# Returns true if there is a subset
# of arr[] with sum divisible by m
def modularSum(arr, n, m):
 
    if (n > m):
        return True
 
    # This array will keep track of all
    # the possible sum (after modulo m)
    # which can be made using subsets of arr[]
    # initialising boolean array with all false
    DP = [False for i in range(m)]
 
    # we'll loop through all the elements of arr[]
    for i in range(n):
     
        # anytime we encounter a sum divisible
        # by m, we are done
        if (DP[0]):
            return True
 
        # To store all the new encountered sum (after
        # modulo). It is used to make sure that arr[i]
        # is added only to those entries for which DP[j]
        # was true before current iteration.
        temp = [False for i in range(m)]
 
        # For each element of arr[], we loop through
        # all elements of DP table from 1 to m and
        # we add current element i. e., arr[i] to
        # all those elements which are true in DP
        # table
        for j in range(m):
         
            # if an element is true in DP table
            if (DP[j] == True):
             
                if (DP[(j + arr[i]) % m] == False):
 
                    # We update it in temp and update
                    # to DP once loop of j is over
                    temp[(j + arr[i]) % m] = True
             
        # Updating all the elements of temp
        # to DP table since iteration over
        # j is over
        for j in range(m):
            if (temp[j]):
                DP[j] = True
 
        # Also since arr[i] is a single element
        # subset, arr[i]%m is one of the possible
        # sum
        DP[arr[i] % m] = True
     
    return DP[0]
 
# Driver code
arr = [1, 7]
n = len(arr)
m = 5
print("YES") if(modularSum(arr, n, m)) else print("NO")
 
# This code is contributed by Anant Agarwal.


C#
// C# program to check if there is
// a subset with sum divisible by m.
using System;
 
class GFG {
     
// Returns true if there is a subset
// of arr[] with sum divisible by m
static bool modularSum(int []arr, int n,
                                  int m)
{
    if (n > m)
        return true;
  
    // This array will keep track of all
    // the possible sum (after modulo m)
    // which can be made using subsets of arr[]
    // initialising boolean array with all false
    bool []DP=new bool[m];
    for (int l=0;l


PHP
 $m)
        return true;
 
    // This array will keep track of all
    // the possible sum (after modulo m)
    // which can be made using subsets of arr[]
    // initialising boolean array with all false
    $DP = Array_fill(0, $m, false);
 
    // we'll loop through all the elements of arr[]
    for ($i = 0; $i < $n; $i++)
    {
        // anytime we encounter a sum divisible
        // by m, we are done
        if ($DP[0])
            return true;
 
        // To store all the new encountered sum
        // (after modulo). It is used to make
        // sure that arr[i] is added only to those 
        // entries for which DP[j] was true before
        // current iteration.
        $temp = array_fill(0, $m, false) ;
 
        // For each element of arr[], we loop through
        // all elements of DP table from 1 to m and
        // we add current element i. e., arr[i] to
        // all those elements which are true in DP
        // table
        for ($j = 0; $j < $m; $j++)
        {
            // if an element is true in DP table
            if ($DP[$j] == true)
            {
                if ($DP[($j + $arr[$i]) % $m] == false)
 
                    // We update it in temp and update
                    // to DP once loop of j is over
                    $temp[($j + $arr[$i]) % $m] = true;
            }
        }
 
        // Updating all the elements of temp
        // to DP table since iteration over
        // j is over
        for ($j = 0; $j < $m; $j++)
            if ($temp[$j])
                $DP[$j] = true;
 
        // Also since arr[i] is a single element
        // subset, arr[i]%m is one of the possible
        // sum
        $DP[$arr[$i] % $m] = true;
    }
 
    return $DP[0];
}
 
// Driver Code
$arr = array(1, 7);
$n = sizeof($arr);
$m = 5;
 
if (modularSum($arr, $n, $m) == true )
    echo "YES\n";
else
    echo "NO\n";
 
// This code is contributed by Ryuga
?>


Javascript


输出:

NO

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程