📜  最大可分割对子集

📅  最后修改于: 2021-04-29 18:33:29             🧑  作者: Mango

给定n个不同元素的数组,请找到最大子集的长度,以使子集中的每个对都可以使该对中的较大元素可被较小的元素整除。

例子:

Input : arr[] = {10, 5, 3, 15, 20} 
Output : 3 
Explanation: The largest subset is 10, 5, 20.
10 is divisible by 5, and 20 is divisible by 10.

Input : arr[] = {18, 1, 3, 6, 13, 17} 
Output : 4
Explanation: The largest subset is 18, 1, 3, 6,
In the subsequence, 3 is divisible by 1, 
6 by 3 and 18 by 6.

这可以使用动态编程解决。我们从头开始遍历排序后的数组。对于每个元素a [i],我们计算dp [i],其中dp [i]表示最大可分割子集的大小,其中a [i]是最小元素。我们可以使用从dp [i + 1]到dp [n-1]的值来计算数组中的dp [i]。最后,我们从dp []返回最大值。

下面是上述方法的实现:

C++
// CPP program to find the largest subset which
// where each pair is divisible.
#include 
using namespace std;
 
// function to find the longest Subsequence
int largestSubset(int a[], int n)
{
    // dp[i] is going to store size of largest
    // divisible subset beginning with a[i].
    int dp[n];
 
    // Since last element is largest, d[n-1] is 1
    dp[n - 1] = 1;
 
    // Fill values for smaller elements.
    for (int i = n - 2; i >= 0; i--) {
 
        // Find all multiples of a[i] and consider
        // the multiple that has largest subset
        // beginning with it.
        int mxm = 0;
        for (int j = i + 1; j < n; j++)
            if (a[j] % a[i] == 0 || a[i] % a[j] == 0)
                mxm = max(mxm, dp[j]);
 
        dp[i] = 1 + mxm;
    }
 
    // Return maximum value from dp[]
    return *max_element(dp, dp + n);
}
 
// driver code to check the above function
int main()
{
    int a[] = { 1, 3, 6, 13, 17, 18 };
    int n = sizeof(a) / sizeof(a[0]);
    cout << largestSubset(a, n) << endl;
    return 0;
}


Java
import java.util.Arrays;
 
// Java program to find the largest
// subset which was each pair
// is divisible.
class GFG {
 
    // function to find the longest Subsequence
    static int largestSubset(int[] a, int n)
    {
        // dp[i] is going to store size of largest
        // divisible subset beginning with a[i].
        int[] dp = new int[n];
 
        // Since last element is largest, d[n-1] is 1
        dp[n - 1] = 1;
 
        // Fill values for smaller elements.
        for (int i = n - 2; i >= 0; i--) {
 
            // Find all multiples of a[i] and consider
            // the multiple that has largest subset
            // beginning with it.
            int mxm = 0;
            for (int j = i + 1; j < n; j++) {
                if (a[j] % a[i] == 0 || a[i] % a[j] == 0) {
                    mxm = Math.max(mxm, dp[j]);
                }
            }
 
            dp[i] = 1 + mxm;
        }
 
        // Return maximum value from dp[]
        return Arrays.stream(dp).max().getAsInt();
    }
 
    // driver code to check the above function
    public static void main(String[] args)
    {
        int[] a = { 1, 3, 6, 13, 17, 18 };
        int n = a.length;
        System.out.println(largestSubset(a, n));
    }
}
 
/* This JAVA code is contributed by Rajput-Ji*/


Python3
# Python program to find the largest
# subset where each pair is divisible.
 
# function to find the longest Subsequence
def largestSubset(a, n):
     
    # dp[i] is going to store size
    # of largest divisible subset
    # beginning with a[i].
    dp = [0 for i in range(n)]
     
    # Since last element is largest,
    # d[n-1] is 1
    dp[n - 1] = 1;
 
    # Fill values for smaller elements
    for i in range(n - 2, -1, -1):
         
        # Find all multiples of a[i]
        # and consider the multiple
        # that has largest subset    
        # beginning with it.
        mxm = 0;
        for j in range(i + 1, n):
            if a[j] % a[i] == 0 or a[i] % a[j] == 0:
                mxm = max(mxm, dp[j])
        dp[i] = 1 + mxm
         
    # Return maximum value from dp[]
    return max(dp)
 
# Driver Code
a = [ 1, 3, 6, 13, 17, 18 ]
n = len(a)
print(largestSubset(a, n))
 
# This code is contributed by
# sahil shelangia


C#
// C# program to find the largest
// subset which where each pair
// is divisible.
using System;
using System.Linq;
 
public class GFG {
 
    // function to find the longest Subsequence
    static int largestSubset(int[] a, int n)
    {
        // dp[i] is going to store size of largest
        // divisible subset beginning with a[i].
        int[] dp = new int[n];
 
        // Since last element is largest, d[n-1] is 1
        dp[n - 1] = 1;
 
        // Fill values for smaller elements.
        for (int i = n - 2; i >= 0; i--) {
 
            // Find all multiples of a[i] and consider
            // the multiple that has largest subset
            // beginning with it.
            int mxm = 0;
            for (int j = i + 1; j < n; j++)
                if (a[j] % a[i] == 0 | a[i] % a[j] == 0)
                    mxm = Math.Max(mxm, dp[j]);
 
            dp[i] = 1 + mxm;
        }
 
        // Return maximum value from dp[]
        return dp.Max();
    }
 
    // driver code to check the above function
    static public void Main()
    {
        int[] a = { 1, 3, 6, 13, 17, 18 };
        int n = a.Length;
        Console.WriteLine(largestSubset(a, n));
    }
}
 
// This code is contributed by vt_m.


PHP
= 0; $i--)
    {
 
        // Find all multiples of
        // a[i] and consider
        // the multiple that
        // has largest subset
        // beginning with it.
        $mxm = 0;
        for ($j = $i + 1; $j < $n; $j++)
            if ($a[$j] % $a[$i] == 0 or $a[$i] % $a[$j] == 0)
                $mxm = max($mxm, $dp[$j]);
 
        $dp[$i] = 1 + $mxm;
    }
 
    // Return maximum value
    // from dp[]
    return max($dp);
}
 
    // Driver Code
    $a = array(1, 3, 6, 13, 17, 18);
    $n = count($a);
    echo largestSubset($a, $n);
     
// This code is contributed by anuj_67.
?>


Javascript


输出:

4

时间复杂度: O(n * n)