📜  总和可被M |整除的子集数套装2

📅  最后修改于: 2021-05-06 17:34:05             🧑  作者: Mango

给定一个由N个整数组成的数组arr []和一个整数M ,任务是找到非空子序列的数量,以使子序列的和可被M整除。

例子:

方法:本文讨论了一种基于动态编程的方法,具有O(N * SUM)时间复杂度,其中N是数组的长度, SUM是所有数组元素的总和。

在本文中,将讨论对先前方法的改进。代替总和作为DP的状态之一,(总和%m)将用作DP的状态之一,因为足够了。因此,时间复杂度可以归结为O(m * N)。

递归关系:

现在让我们定义状态, dp [i] [curr]仅仅表示子数组arr [i…N-1]的子集数,从而(其元素的总和+ curr)%m = 0

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
#define maxN 20
#define maxM 10
  
// To store the states of DP
int dp[maxN][maxM];
bool v[maxN][maxM];
  
// Function to find the required count
int findCnt(int* arr, int i, int curr, int n, int m)
{
    // Base case
    if (i == n) {
        if (curr == 0)
            return 1;
        else
            return 0;
    }
  
    // If the state has been solved before
    // return the value of the state
    if (v[i][curr])
        return dp[i][curr];
  
    // Setting the state as solved
    v[i][curr] = 1;
  
    // Recurrence relation
    return dp[i][curr] = findCnt(arr, i + 1,
                                 curr, n, m)
                         + findCnt(arr, i + 1,
                                   (curr + arr[i]) % m,
                                   n, m);
}
  
// Driver code
int main()
{
    int arr[] = { 3, 3, 3, 3 };
    int n = sizeof(arr) / sizeof(int);
    int m = 6;
  
    cout << findCnt(arr, 0, 0, n, m) - 1;
  
    return 0;
}


Java
// Java implementation of the approach
class GFG
{
static int maxN = 20;
static int maxM = 10;
  
// To store the states of DP
static int [][]dp = new int[maxN][maxM];
static boolean [][]v = new boolean[maxN][maxM];
  
// Function to find the required count
static int findCnt(int[] arr, int i, 
                   int curr, int n, int m)
{
    // Base case
    if (i == n) 
    {
        if (curr == 0)
            return 1;
        else
            return 0;
    }
  
    // If the state has been solved before
    // return the value of the state
    if (v[i][curr])
        return dp[i][curr];
  
    // Setting the state as solved
    v[i][curr] = true;
  
    // Recurrence relation
    return dp[i][curr] = findCnt(arr, i + 1,
                                 curr, n, m) + 
                         findCnt(arr, i + 1,
                                (curr + arr[i]) % m,
                                 n, m);
}
  
// Driver code
public static void main(String[] args)
{
    int arr[] = { 3, 3, 3, 3 };
    int n = arr.length;
    int m = 6;
  
    System.out.println(findCnt(arr, 0, 0, n, m) - 1);
}
}
  
// This code is contributed by 29AjayKumar


Python3
# Python3 implementation of the approach
maxN = 20
maxM = 10
  
# To store the states of DP
dp = [[0 for i in range(maxN)] 
         for i in range(maxM)]
v = [[0 for i in range(maxN)] 
        for i in range(maxM)]
  
# Function to find the required count
def findCnt(arr, i, curr, n, m):
      
    # Base case
    if (i == n):
        if (curr == 0):
            return 1
        else:
            return 0
  
    # If the state has been solved before
    # return the value of the state
    if (v[i][curr]):
        return dp[i][curr]
  
    # Setting the state as solved
    v[i][curr] = 1
  
    # Recurrence relation
    dp[i][curr] = findCnt(arr, i + 1, 
                          curr, n, m) + \
                  findCnt(arr, i + 1,
                         (curr + arr[i]) % m, n, m)
    return dp[i][curr]
  
# Driver code
arr = [3, 3, 3, 3]
n = len(arr)
m = 6
  
print(findCnt(arr, 0, 0, n, m) - 1)
  
# This code is contributed by Mohit Kumar


C#
// C# implementation of the approach 
using System;
  
class GFG 
{ 
    static int maxN = 20; 
    static int maxM = 10; 
      
    // To store the states of DP 
    static int [,]dp = new int[maxN, maxM]; 
    static bool [,]v = new bool[maxN, maxM]; 
      
    // Function to find the required count 
    static int findCnt(int[] arr, int i, 
                       int curr, int n, int m) 
    { 
        // Base case 
        if (i == n) 
        { 
            if (curr == 0) 
                return 1; 
            else
                return 0; 
        } 
      
        // If the state has been solved before 
        // return the value of the state 
        if (v[i, curr]) 
            return dp[i, curr]; 
      
        // Setting the state as solved 
        v[i, curr] = true; 
      
        // Recurrence relation 
        return dp[i, curr] = findCnt(arr, i + 1, 
                                     curr, n, m) +
                             findCnt(arr, i + 1, 
                                    (curr + arr[i]) % m, n, m); 
    } 
      
    // Driver code 
    public static void Main() 
    { 
        int []arr = { 3, 3, 3, 3 }; 
        int n = arr.Length; 
        int m = 6; 
      
        Console.WriteLine(findCnt(arr, 0, 0, n, m) - 1); 
    } 
}
  
// This code is contributed by kanugargng


输出:
7