Computer >> 컴퓨터 >  >> 프로그램 작성 >> C++

배열에서 가장 큰 분할 가능한 부분 집합을 찾는 C++ 프로그램

<시간/>

이 자습서에서는 고유한 양의 정수 배열이 제공되는 문제에 대해 설명합니다. 모든 쌍에 대해 더 큰 요소가 더 작은 요소로 나뉘도록 가장 큰 부분집합을 찾아야 합니다. 예를 들어 -

Input: nums[ ] = { 1, 4, 2, 6, 7}
Output: 1 2 4
Explanation:
All Divisible subsets are: (1, 2, 4), (1, 2, 6), (1, 7), etc
We have 2 subsets of length 3 in which all the pairs satisfy the condition.

Input: nums[ ] = { 1, 2, 3, 6 }
Output: 6 2 1

해결책을 찾기 위한 접근 방식

이 튜토리얼에서 설명할 두 가지 접근 방식이 있습니다.

간단한 접근

간단한 접근 방식으로 재귀를 적용하여 이 문제를 해결할 수 있습니다. 각 요소를 가져와서 하위 집합에 포함해야 하는지 여부를 확인합니다. 첫 번째 요소부터 시작한다고 가정해 보겠습니다. 하위 집합에 포함하거나 첫 번째 요소에 포함하지 않는 두 가지 옵션이 있습니다. 첫 번째 요소를 포함해 보겠습니다. 그런 다음 두 번째 요소가 하위 집합에 포함되려면 하위 문자열의 요소, 즉 첫 번째 요소로 나눌 수 있거나 나눌 수 있어야 합니다. 이것이 우리가 어레이 전체에 걸쳐 진행하는 방법입니다. 따라서 O(2^n)의 시간 복잡도를 생성하는 2^n 가능한 경로가 있습니다. 이 문제를 해결하기 위한 실행 가능한 접근 방식을 살펴보겠습니다.

효율적인 접근

이 문제에서 동적 프로그래밍을 사용하면 효율적인 접근 방식을 적용할 수 있습니다.

  • 배열을 정렬하여 올바른 요소로 나눌 수 있는 왼쪽 요소를 가져옵니다. 나눗셈을 한 번 확인해야 합니다.

  • 가장 긴 증가 부분 시퀀스, 즉 dp[ ] 배열을 사용하여 i번째 인덱스까지 나눌 수 있는 가장 큰 부분 집합을 저장합니다. 모든 요소가 자체적으로 분할되기 때문에 각 인덱스를 1로 초기화합니다.

  • 이제 두 번째 인덱스에서 반복하고 현재 인덱스로 끝나는 최대 나눌 수 있는 부분 집합에 대해 각 요소를 확인합니다. 이러한 방식으로 각 인덱스의 최대 하위 집합을 찾습니다.

  • 이제 배열을 탐색하고 모든 요소에 대해 나눌 수 있는 개수가 가장 큰 제수를 찾습니다. 그리고 현재 인덱스의 나눌 수 있는 개수 값을 해당 요소의 나눌 수 있는 개수 + 1로 변경합니다.

예시

위 접근 방식에 대한 C++ 코드

#include<bits/stdc++.h>
using namespace std;
int main(){
    int nums[] = {1, 2, 3, 6};
    int n = sizeof(nums)/sizeof(int);
    // sorting the array to exclude one condition for division.
    sort(nums, nums+n);
    vector <int> prev_res(n, -1);
    // vector to store divisors of all the elements
    vector <int> dp(n, 1);
    int max = 1;
    for (int i=1; i<n; i++){   // Check if there's a divisor of ith element present at jth index.
        for (int j=0; j<i; j++){
            if (nums[i]%nums[j] == 0){
            // check If adding that increases the number of elements in subsequence.
                if (dp[i] < dp[j] + 1){
                    dp[i] = dp[j]+1;
                    prev_res[i] = j;
                   
                }
            }
        }
   
        // finding index having a maximum number of subsets.
        if(max<dp[i])
            max = dp[i];
    }
    cout << "Largest divisible subset in the array: ";
    // printing the maximum subset
    int k = max;
    while (k >= 0){
        cout << nums[k] << " ";
        k = prev_res[k];
    }
    return 0;
}

출력

Largest divisible subset in the array: 6 2 1

결론

이 튜토리얼에서 우리는 문제에 대해 논의했습니다. 주어진 배열에서 각 쌍의 정수를 나눌 수 있는 가장 큰 나눌 수 있는 부분집합을 찾아야 합니다. 우리는 기하급수적인 시간 복잡도를 생성하는 재귀의 접근 방식에 대해 논의했기 때문에 동적 프로그래밍 솔루션에 대해 논의했습니다. 우리는 또한 C, Java, Python 등과 같은 프로그래밍 언어로 할 수 있는 이 문제에 대한 C++ 프로그램에 대해 논의했습니다. 이 튜토리얼이 도움이 되기를 바랍니다.