给定一组非负的不同整数和一个值 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 现场工作专业课程和学生竞争性编程现场课程。