📜  计算 GCD 等于 X 的子序列

📅  最后修改于: 2022-05-13 01:56:04.271000             🧑  作者: Mango

计算 GCD 等于 X 的子序列

给定一个由N个整数和一个正整数X组成的数组arr[] ,任务是用 GCD 精确计数X的子序列。

例子:

方法:给定的问题可以在动态规划的帮助下解决。请按照以下步骤解决给定的问题。

  • 定义一个二维 dp 表dp[i][j] ,它将表示有效子序列的数量,直到索引i与 GCD(= j )。
  • 对于每次迭代,我们有 2 个选择:
    • 取当前元素: dp 表可以更新为dp[i + 1][gcd(j, arr[i])] += dp[i][j]
    • 跳过当前元素: dp 表可以更新为dp[i+1][j] += dp[i][j]
  • 基本情况是dp[0][0] = 1
  • 由于两个数的 gcd 永远不会大于这两个数,所以j的值将达到数组中的最大元素。因此,它可以迭代求解,最终答案将是dp[N][X]

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to find the total subsequences
// having GCD = X
int totalValidSubsequences(
    vector arr, int X, int N)
{
    // Find the maximum element of
    // the array
    int mx = *max_element(
        arr.begin(), arr.end());
 
    // Check if X is greater than mx
    if (X > mx) {
        return 0;
    }
    // Make a 2-d dp table of
    // size [n+1, mx + 1]
    vector > dp(
        N + 1, vector(mx + 1, 0));
 
    // Base Case
    dp[0][0] = 1;
 
    for (int i = 0; i < N; i++) {
 
        // Iterate through all possible
        // indexes
        for (int j = 0; j <= mx; j++) {
 
            // Iterate through all
            // possible values
 
            // Case 1. Skip the element
            dp[i + 1][j] += dp[i][j];
 
            // Case 2. Skip the current element
            dp[i + 1][__gcd(j, arr[i])] += dp[i][j];
        }
    }
 
    // Return the answer dp[N][X]
    return dp[N][X];
}
 
// Driver Code
int main()
{
    vector arr = { 6, 4, 30 };
    int X = 2;
    int N = arr.size();
    cout << totalValidSubsequences(arr, X, N);
 
    return 0;
}


Java
// Java program for the above approach
 
import java.io.*;
import java.util.Arrays;
import java.util.Collections;
 
class GFG {
       
       // Function to find maximum in arr[]
     static int max(int[] arr)
     {
            
         // Initialize maximum element
         int max = arr[0];
         
         // Traverse array elements from second and
         // compare every element with current max 
         for (int i = 1; i < arr.length; i++)
             if (arr[i] > max)
                 max = arr[i];
         
         return max;
     }
   
      // Recursive function to return gcd of a and b
      static int gcd(int a, int b)
    {
      if (b == 0)
        return a;
      return gcd(b, a % b);
    }
 
    // Function to find the total subsequences
    // having GCD = X
    static int totalValidSubsequences(int[] arr,
                                      int X, int N)
    {
        // Find the maximum element of
        // the array
        int mx = max(arr);
 
        // Check if X is greater than mx
        if (X > mx) {
            return 0;
        }
        // Make a 2-d dp table of
        // size [n+1, mx + 1]
        int dp[][] = new int[N + 1][mx + 1];
 
        // Base Case
        dp[0][0] = 1;
 
        for (int i = 0; i < N; i++) {
 
            // Iterate through all possible
            // indexes
            for (int j = 0; j <= mx; j++) {
 
                // Iterate through all
                // possible values
 
                // Case 1. Skip the element
                dp[i + 1][j] += dp[i][j];
 
                // Case 2. Skip the current element
                dp[i + 1][gcd(j, arr[i])] += dp[i][j];
            }
        }
 
        // Return the answer dp[N][X]
        return dp[N][X];
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int arr[] = { 6, 4, 30 };
           int X = 2;
        int N = arr.length;
           System.out.println(totalValidSubsequences(arr, X, N));
    }
}
 
// This code is contributed by Dharanendra L V.


Python3
# Python 3 program for the above approach
from math import gcd
 
# Function to find the total subsequences
# having GCD = X
def totalValidSubsequences(arr, X, N):
   
    # Find the maximum element of
    # the array
    mx = max(arr)
 
    # Check if X is greater than mx
    if (X > mx):
        return 0
    # Make a 2-d dp table of
    # size [n+1, mx + 1]
    dp = [[0 for i in range(mx+1)] for j in range(N + 1)]
 
    # Base Case
    dp[0][0] = 1
 
    for i in range(N):
       
        # Iterate through all possible
        # indexes
        for j in range(mx+1):
           
            # Iterate through all
            # possible values
 
            # Case 1. Skip the element
            dp[i + 1][j] += dp[i][j]
 
            # Case 2. Skip the current element
            dp[i + 1][gcd(j, arr[i])] += dp[i][j]
 
    # Return the answer dp[N][X]
    return dp[N][X]
 
# Driver Code
if __name__ == '__main__':
    arr = [6, 4, 30]
    X = 2
    N = len(arr)
    print(totalValidSubsequences(arr, X, N))
     
    # This code is contributed by SURENDRA_GANGWAR.


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG{
 
       // Function to find maximum in arr[]
static int max(int []arr)
{
   
  // Initialize maximum element
  int max = arr[0];
   
  // Traverse array elements from second and
  // compare every element with current max 
  for (int i = 1; i < arr.Length; i++)
             if (arr[i] > max)
                 max = arr[i];
         
         return max;
}
 
 
// Recursive function to return gcd of a and b
static int gcd(int a, int b)
{
 if (b == 0)
        return a;
      return gcd(b, a % b);
}
 
 
// Function to find the total subsequences
// having GCD = X
static int totalValidSubsequences(int[] arr,
                                      int X, int N)
    {
        // Find the maximum element of
        // the array
        int mx = max(arr);
 
        // Check if X is greater than mx
        if (X > mx) {
            return 0;
        }
        // Make a 2-d dp table of
        // size [n+1, mx + 1]
        int[,] dp = new int[N + 1, mx + 1];
 
        // Base Case
        dp[0, 0] = 1;
 
        for (int i = 0; i < N; i++) {
 
            // Iterate through all possible
            // indexes
            for (int j = 0; j <= mx; j++) {
 
                // Iterate through all
                // possible values
 
                // Case 1. Skip the element
                dp[i + 1, j] += dp[i, j];
 
                // Case 2. Skip the current element
                dp[i + 1, gcd(j, arr[i])] += dp[i, j];
            }
        }
 
        // Return the answer dp[N][X]
        return dp[N, X];
    }
 
 
 
// Driver Code
public static void Main()
{
   int[] arr = { 6, 4, 30 };
           int X = 2;
        int N = arr.Length;
           Console.Write(totalValidSubsequences(arr, X, N));
}
}
 
// This code is contributed by _saurabh_jaiswal


Javascript


输出:
3

时间复杂度: O(N*M),其中M数组的最大元素
辅助空间: O(N*M)