给定一组非负的不同整数和一个值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 []的每个元素,然后添加(模m)j,其具有DP [j] = true并将所有这样的(j + arr [i])%m可能子集和存储在布尔值中数组temp,在j迭代结束时,我们用temp更新DP表。同样,我们将arr [i]添加到DP中,即DP [arr [i]%m] = true。
最后,如果DP [0]为true,则表示是,则存在一个总和可被m整除的子集,否则为否。
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
?>
输出:
NO
时间复杂度: O(m ^ 2)
辅助空间: O(m)